我在Tomcat上运行Java Web应用程序来为客户端创建预定事件。我有一个关于底层操作系统,Tomcat和JVM的默认日期时间的问题。
当我通过Java代码检索Date
时,它与底层操作系统类似。然后我更改了操作系统时间只是为了模拟夏令时效果,但应用程序没有反映操作系统时间。
然后我阅读了更多关于它的内容,发现JRE负责维护JVM的日期时间。但是,当我重新启动tomcat时,它开始反映操作系统时间。
任何人都能解释一下这背后的理论吗?根据我的读数,我们可以使用TZupdater更新JRE的最新日期时间更改,系统将处理夏令时而无需重新启动tomcat。
答案 0 :(得分:4)
这里涉及不同的设置:
操作系统和JVM的时区设置正在为您处理夏令时(夏令时,夏令时)。因此,设置系统时间以反映DST是不正确的方法。相反,您应该将操作系统时区设置为所需的时区,操作系统将自动调整DST在春季开始和秋季结束时显示的时间。
您真的不应该使用Date
来表示日期和时间。该类已经过时了,java.time的类,现代Java日期和时间API,可以更好地使用。如果您仍然这样做,则Date
不包含您所在时区的时间。相反,它代表时间线上与时区无关的点。令许多人感到困惑的是,当您打印日期,从而隐式调用其toString
方法时,那个toString
方法会抓取您的JVM的时区设置并使用它来生成字符串。这可能会让您误以为Date
中有时区。
现在我提到了JVM时区设置。除非执行某些操作以获取其他内容,否则在启动JVM时,JVM时区设置将初始化为操作时区设置,但即使更改操作系统设置也不会更改。另一方面,可以从JVM中运行的Java程序更改JVM设置(这包括在Tomcat服务器中运行的任何程序)。
通常,在Java中获取当前时间的最佳方法是自己指定时区。例如:
System.out.println(ZonedDateTime.now(ZoneId.of("Pacific/Noumea")));
这只是打印
2018-03-06T06:20:23.903292 + 11:00 [太平洋/努美阿]
发生了什么事情是Java从操作系统时钟中取出当前时间并将其转换为指定时区的当前时间,如果DST在一年中的这个时间生效,则将DST考虑在内。与Date
相反,ZonedDateTime
是日期和时间和时区。 ZonedDateTime
是java.time中的一个类,我提到的现代API。
通过指定显式时区,您可以独立于可能无法预测的任何设置。通过依赖您所需的时区,您可以在DST开始和结束时更改系统时钟。
是的,您可能需要使用TZupdater来确保您的JVM包含正确的信息,例如您所在时区的DST。政治家有时会在短时间内更改DST规则,而世界上的Java安装在发生这种情况时不会自动更改。升级Java版本时,通常还会获得最新的时区信息。但是,如果您使用的是一个不那么全新的Java版本,TZupdater可以确保您的时区信息是最新的。