我的应用程序严重依赖于Java。我们做了大量的日志记录,数据库插入等。在白天的灯光定时开关之后,我们注意到所有的Java时间都落后了大约一个小时。我们的版本是1.6_18。我认为这个问题在早期版本的Java中得到了解决。如果有任何补丁,请建议可以做什么。
答案 0 :(得分:5)
定期修改时区信息。 Java 6更新18可能会为您的位置设置过时的DST设置。
升级到最新版本(update 25)或运行TZupdater工具。
编辑:我刚刚发现Oracle提供了RSS feed for timezone updates。如果您的应用程序必须具有最新的TZ数据,请密切注意这一点。答案 1 :(得分:2)
将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 8及更高版本中。这些类取代了麻烦的旧日期时间类,例如java.util.Date
,.Calendar
和& java.text.SimpleDateFormat
。
现在位于Joda-Time的maintenance 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的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
等。