[英]ZonedDateTime to java.util.Date -> EST to UTC - Off by 1 hour
[英]Using new java.util.Date() Returns An Hour Behind With DST
我有一个在Linux虚拟机上运行的Java程序作为cron作业。 目前存在一个问题,以下行用作记录存储当前日期和时间的一部分:
String date = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss").format(new Date());
在今天夏令时之后,确定系统日期未正确设置,因为它没有更新。 使用以下命令修复此问题并重新启动Linux环境后,日期现在正确并更新为夏令时。
ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
但是,当Java程序作为cron作业的一部分执行时,日期仍然落后一小时。 这会导致内部发生计时问题,因为new Date()
用于获取当前系统时间,从而导致进程中的后续问题。 例如,在下午5:00,Java程序输出4:00 PM。 这个实现还有其他考虑因素吗? new Date()
不应该总是返回当前的系统日期吗?
将调试行添加到cron作业,这将执行预期的正确时间。
Date
类 新的Date()不应该总是返回当前的系统日期吗?
是的, Date
类始终以UTC格式捕获当前时刻。 让我再说一遍: Date
以UTC记录时刻。
问题来自该类' toString
方法的善意但不幸的“特性”,其中JVM的当前默认时区应用于生成该字符串 。 避免这种过时和麻烦的课程的众多原因之一。
我怀疑您的“tzdata”时区数据文件已过时,无法识别DST切换的新日期。
Java实现通常在启动时从主机OS获取其当前的默认时区。 在JVM之后,更改主机操作系统的时区对JVM没有影响。
重新启动JVM以在主机操作系统中选择新的区域设置。
最佳做法通常是将服务器设置为UTC。 那你就不用担心夏令时废话了。
您的编程,日志记录,计算机作业,数据交换和数据序列化的大部分应该是UTC。
请注意,例如,Stack Overflow如何使用UTC报告“今天”和“昨天”的活动。 学会将UTC视为真正的时间; 所有区域都是该主题的变体。
仅在关键时刻应用时区,例如向期望某个区域的用户进行演示。
请记住,您的问题不是由于时空的弯曲造成的。 按UTC计算,秒,分钟和小时数继续正常增加,滴答滴答滴答声。 您的问题在于误译为时区,其中包含过时的时区规则更改数据。
您的Java应用程序应始终明确指定其所需/预期的时区。 如果省略,则隐式应用JVM的当前默认时区。
JVM默认值可以随时由JVM中任何应用程序的任何线程中的任何代码更改,并立即影响该JVM中的所有其他代码。 因此,永远不要依赖于当前的默认值。 与用户确认,并在您的代码中明确指定。
旧日期时间类包括Date
和Calendar
是一个血腥的混乱。 避免他们。 它们现在已经遗留下来,取而代之的是java.time类。
Instant
类是时间线上的一个时刻,分辨率为纳秒,始终为UTC。
Instant instant = Instant.now() ;
要生成标准的ISO 8601格式化字符串,请调用toString
。 最后的Z
是Zulu的缩写,意思是UTC。
String output = instant.toString() ;
2017-01-23T12:34:56.123456789Z
使用这两行简单的代码可以避免您的整个问题。
但是你应该经常更新tzdata:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.