我在几个小时内努力了解代码中TimeStamp
的内容。
Oracle DB和Java应用程序都在PDT中
从DB中选择:
select id, time_stamp from some_Table where id = '3de392d69c69434eb907f1c0d2802bf0';
3de392d69c69434eb907f1c0d2802bf0 09-DEC-2014 12.45.41.354000000 PM
select id, time_stamp at time zone 'UTC' from some_Table where id = '3de392d69c69434eb907f1c0d2802bf0';
3de392d69c69434eb907f1c0d2802bf0 09-DEC-2014 12.45.41.354000000 PM
Oracle数据库中的字段为TimeStamp
,因此不存储时区信息。
Timestamp dbTimeStamp = dbRecord.getLastLoginTime();
System.out.println(dbTimeStamp.toString()); // 2014-12-09 12:16:50.365
System.out.println(dbTimeStamp.getTime()); // 1418156210365 --> Tue Dec 09 2014 20:16:50 UTC?
根据documentation,getTime()
返回自1970年1月1日00:00:00 GMT以来的毫秒数 由此Timestamp对象表示。
为什么将8 hours (PDT - UTC)
的额外时间添加到getTime()
的响应中?
答案 0 :(得分:4)
TimeStamp.toString()
在内部使用其{javadoc声明的Date.getHours()
:
返回此Date对象表示的小时。该 返回值是一个数字(0到23) 表示包含或开始的当天内的小时 与此日期所代表的即时时间 对象,在本地时区解释。
因此toString
正在使用您当地的时区,而getDate
则没有。
答案 1 :(得分:3)
这两者是相互一致的。 getTime()
方法为您提供绝对毫秒值,您选择以UTC格式解释。 toString()
方法为您提供在关联时区中解释的相同毫秒值。因此,添加时间不是getTime()
,而是减去它的toString()
。这并没有真正记录,但这就是它的行为方式。
最重要的外卖应该是不要依赖Timestamp.toString
因为它具有误导性。很久以前,Date
(和Timestamp
是一个子类)中的整个时区机制已被弃用。而是仅使用getTime()
值并将其格式化为其他API,例如Java 8 Date / Time API。
显然,toString()
输出实际上是正确的输出,对我而言,这只是Java日期/时间处理错误的粗略目录的一小部分。您可能会从数据库中收到格式化字符串的时间戳,而不是毫秒值。 JDBC然后根据与Timestamp
实例关联的时区将其解析为毫秒值,以使toString()
的输出与数据库返回的输出匹配,并且实际的毫秒值是次要的。
答案 2 :(得分:0)
感谢上面的答案以及关于SO的参考资料。 This answer终于帮助我理解了在理解TimeStamps时出错的地方。
从链接的答案中进行评论
Note: Timestamp.valueOf("2010-10-23 12:05:16"); means "create a timestamp with the given time in the default timezone".
TimeStamp代表一个时刻。默认情况下,当前时区中的那个时刻。
写入到数据库的时间戳是UTC时刻。即正在编写当前的UTC时间。因此,无论应用程序部署在何处,写入数据库的值都与TimeStamp相同。
但是,在读取生成的TimeStamp时,会假定从部署JVM读取的默认TimeZone。因此,读取的值是PST时区中的瞬间。实际UTC值比PST时间多8小时。因此,差异。
TimeStamp.getTime()
返回UTC的毫秒数。
TimeStamp.toString()
返回当前TimeZone
中的时间表示。谢谢@marko-topolnik
举个例子,
2014-12-09 12:16:50.365
2014-12-09 12:16:50.365
2014-12-09 20:16:50
因此,解决方案是将TimeZone
偏移量添加到从数据库读取的值,以使时间为UTC
TimeStamps。
这里的关键是" TimeStamp is a time instant without TimeZone information. The timestamp is assumed to be relative to the default system TimeZone.
" - 我花了很长时间才理解这一点。