Java时间落后一小时

时间:2011-05-04 01:25:44

标签: time java

我的应用程序严重依赖于Java。我们做了大量的日志记录,数据库插入等。在白天的灯光定时开关之后,我们注意到所有的Java时间都落后了大约一个小时。我们的版本是1.6_18。我认为这个问题在早期版本的Java中得到了解决。如果有任何补丁,请建议可以做什么。

2 个答案:

答案 0 :(得分:5)

定期修改时区信息。 Java 6更新18可能会为您的位置设置过时的DST设置。

升级到最新版本(update 25)或运行TZupdater工具。

编辑:我刚刚发现Oracle提供了RSS feed for timezone updates。如果您的应用程序必须具有最新的TZ数据,请密切注意这一点。

答案 1 :(得分:2)

TL;博士

使用UTC

UTC视为“一个真实的时间”。特定时区的任何日期时间都是UTC的推导。在进行编程或系统管理工作时,请忘记您自己的本地时区。我强烈建议为显示UTC的物理和数字桌面添加时钟。在紧要关头,请使用Time.is等网站。

您的大多数业务逻辑,日志记录,数据存储,数据交换和数据库持久性都应该是UTC。调整为时区仅用于演示。

避免旧的日期时间类

避免使用与最早版本的Java捆绑在一起的麻烦旧的旧日期时间类。现在取代了java.time类。

Instant

Instant类代表UTC中时间轴上的一个时刻,分辨率为nanoseconds

Instant now = Instant.now(); // Current moment in UTC.

指定时区

Java虚拟机具有当前默认时区。这可以在主机操作系统启动时获取。或者可以通过配置设置在启动时设置。或者它可能随时被JVM中任何应用程序的任何线程中的任何代码更改 - 在执行期间影响所有其他代码!

鉴于JVM当前的默认时区不同,并且作为程序员无法控制,所以永远不要依赖它。 始终指定所需/预期的时区

通常最好将服务器主机操作系统设置为UTC的时区,但同样,再也不要依赖于编程中的那个。

ZonedDateTime

要将Instant调整为时区,请生成ZonedDateTime个对象。

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );

调用toString以标准ISO 8601格式生成字符串。对于其他格式,请搜索类DateTimeFormatter的堆栈溢出。

更新您的tz时区数据库

时区定义及其异常情况(例如Daylight Saving Time (DST)经常发生频繁变化。

Oracle发布Java的定期更新,其中包含tz database的新副本。如果您无法安装这些Java更新,或者如果一些粗心的政治家对区域进行了近乎最后的更改,您可以使用Oracle的Timezone Updater Tool手动更新Java。

Locale

知道Locale 没有与时区有关。 Locale定义(a)用于翻译的人类语言,以及(b)文化规范决定诸如缩写,标点符号和部分顺序等问题。因此,在使用Locale类时,生成字符串时只需要DateTimeFormatter

Locale l = Locale.CANADA_FRENCH;
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( l );
String output = zdt.format( f );

因此,时区定义日期时间值的含义,但Locale定义其表示

关于java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧日期时间类,例如java.util.Date.Calendar和& java.text.SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。

大部分java.time功能都被反向移植到Java 6& ThreeTen-Backport中的7,并进一步适应Android中的ThreeTenABP(见How to use…)。

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuarter等。