在 Tomcat 中处理夏令时无需重启服务器

ket*_*eth 3 java datetime tomcat dst

我有一个在 Tomcat 上运行的 Java Web 应用程序,用于为客户端创建计划事件。我有一个关于底层操作系统、Tomcat 和 JVM 的默认日期时间的问题。

当我Date通过 Java 代码检索它时,它类似于底层操作系统。然后我更改了操作系统时间只是为了模拟夏令时效果,但应用程序并没有反映操作系统时间。

然后我阅读了更多关于它的内容,发现 JRE 负责维护 JVM 的日期时间。但是,当我重新启动 tomcat 时,它开始反映操作系统时间。

有人可以解释一下这背后的理论吗?作为我的阅读,我们可以使用 TZupdater 更新 JRE 的最新日期时间更改,系统将处理夏令时而无需重启 tomcat。

Ole*_*.V. 5

这里涉及不同的设置:

  • 系统不仅有当前时间,还有时区。
  • Tomcat 运行所在的 JVM 也有时区设置。

操作系统和 JVM 的时区设置为您处理夏令时(夏令时,DST)。所以设置系统时间来反映夏令时是不正确的方法。相反,您应该将操作系统时区设置为所需的时区,操作系统会自动调整它在春季开始夏令时和秋季结束时显示的时间。

您真的不应该Date用于表示日期和时间。该类早已过时,而现代 Java 日期和时间 API 的 java.time 类更易于使用。如果您仍然这样做,Date则您的时区中不包含时间。相反,它代表独立于时区的时间线上的一个点。令很多人感到困惑的是,当您打印日期,从而隐式调用其toString方法时,该toString方法会获取 JVM 的时区设置并将其用于生成字符串。这可能会给您一种错误的印象,即其中Date包含时区。

现在我提到了JVM时区设置。除非采取某些措施以获得其他信息,否则 JVM 时区设置会在 JVM 启动时初始化为操作时区设置,但即使您更改操作系统设置也不会更改。另一方面,JVM 设置可以从在 JVM 中运行的 Java 程序(这包括在 Tomcat 服务器中运行的任何程序)进行更改。

通常,在 Java 中获取当前时间的最佳方法是自己指定时区。例如:

    System.out.println(ZonedDateTime.now(ZoneId.of("Pacific/Noumea")));
Run Code Online (Sandbox Code Playgroud)

这个刚打印

2018-03-06T06:20:23.903292+11:00[太平洋/努美阿]

发生的事情是 Java 从操作系统时钟中获取当前时间并将其转换为指定时区的当前时间,如果 DST 在一年中的这个时间生效,则考虑 DST。与 a 相反DateZonedDateTime是日期和时间以及时区。ZonedDateTime是 java.time 中的类之一,我提到的现代 API。

通过指定明确的时区,您可以独立于任何可能发生不可预测更改的设置。通过依赖您想要的时区,您无需在 DST 开始和结束时更改系统时钟。

是的,您可能需要使用 TZupdater 来确保您的 JVM 包含正确的信息,例如有关您所在时区的 DST 信息,这是正确的。政治家有时会在短时间内更改 DST 规则,而当这种情况发生时,世界上的 Java 安装不会自动更改。当您升级 Java 版本时,您通常还会获得最新的时区信息。但是,如果您使用的不是全新的 Java 版本,TZupdater 是确保您的时区信息是最新的方法。

链接: 关于 java.util.Date