2015-02-11 72 views
2

我的Web应用程序在Apache Tomcat 7.0上运行。我们正在调用java util日历来获取服务器的日期时间。问题是,如果系统时区发生更改,java日历将继续以“旧”时区的日期时间运行。 Tomcat使用os时区更改tomcat需要重启

JDK是 - JDK1.6

你能告诉我们为什么需要tomcat的重启,以反映新的时区?

+0

类似于:[* Java 1.7日光节约变化无法识别*](https://stackoverflow.com/q/29383690/642706) – 2018-03-05 23:23:57

+0

类似于:[*在未启动服务器的情况下处理Tomcat中的夏令时*] (https://stackoverflow.com/q/49113219/642706) – 2018-03-05 23:36:00

回答

1

最好的方法是在Java中使用日期时总是指定时区。或者在Tomcat中与

-Duser.timezone = GMT

参数指定。其他方式Tomcat从系统启动时加载时区。

0

我认为需要重新启动的原因是,没有人愿意为在主动运行并连接到互联网时穿越不同时区的服务器服务。有趣的用例。显然很少见。很稀少。

将您的服务器设置为UTC,使用UTC启动tomcat,然后将您的应用程序配置为在您遇到的任何时区格式化时间 - 问题已解决。

1

tl; dr

尽可能以UTC工作。

Instant.now() // Capture current moment in UTC. 

永远不要依赖主机操作系统,JVM或数据库的当前默认时区设置。明确指定所需/预期的时区。

ZoneId z = ZoneId.of("Africa/Tunis") ; 
ZonedDateTime zdt = instant.atZone(z) ; // Same moment, same point on the timeline, different wall-clock time. 

决不依赖于服务器的时区设置

真正的问题是,你根据在你无法控制,并且可以在任何时刻改变的方面有一些代码:JVM的当前默认时间区。

您不应该编写依赖于系统默认时区的代码。相反,请始终明确指定所需的/预期的时区作为传递给相关类的可选参数。

问题是,如果系统时区已更改,java日历会一直以“旧”时区的日期时间运行。

主机操作系统(OS)有其自己的当前默认时区设置和自己的时区定义(tzdata)。同上你的数据库服务器;如果日期时间处理比较复杂,例如Postgres,它可能在内部存储它自己的tzdata。你的JVM也有它自己当前的默认时区设置和它自己的时区定义(tzdata)。当定义更改感兴趣的时区时,应通过软件产品版本更新或特定于tzdata的更新程序更新所有三个位置中的tzdata

我知道启动时默认启用的所有JVM实现,以将它自己的当前默认时区设置为主机操作系统的默认时区。启动JVM之后,更改主机操作系统时区设置应该对您的JVM没有影响,至少在我见过的Oracle和OpenJDK实现中不会有影响。

我们调用java util calendar来获取服务器的日期时间。

切勿使用麻烦的旧的遗留日期时间类,如Date & Calendar。这些已完全被java.times类取代。

请问为什么tomcat需要重启以反映新的时区?

我猜你的网络应用程序不适当地缓存UTC的偏移量而不是总是使用时区。与UTC的偏移距UTC仅为几个小时 - 分钟的位移。时区更多,是过去,现在和将来对特定地区人民所使用的抵消的变化的历史。所以总是使用时区而不是单纯的偏移量。有关更多详细信息,请参阅my Answer以获得类似的问题。

continent/region的格式指定一个proper time zone name,如America/MontrealAfrica/Casablanca,或Pacific/Auckland。切勿使用3-4字母缩写,如ESTIST,因为它们是而不是真正的时区,不是标准化的,甚至不是唯一的(!)。

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

如果您想使用JVM的当前默认时区,请询问并作为参数传递。如果省略,则隐式应用JVM的当前默认值。更好的是明确的,因为在运行时的任何时候,默认可以通过JVM中任何应用程序的任何线程中的任何代码在任何时刻改变

ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone. 

UTC

一般来说除非最好的区域是由你的业务逻辑或用户界面需要UTC始终工作。你应该学会以UTC来思考,工作,记录,存储和交换数据。在作为程序员或管理员工作时忘记自己的狭隘时区。

Instant类表示UTC中的时间轴上的一个时刻,分辨率为nanoseconds(小数点后最多九(9)位数字)。

Instant instant = Instant.now() ; // Capture current moment in UTC. 

关于java.time

java.time框架是建立在Java 8和更高版本。这些类代替了日期时间类legacy,如java.util.Date,Calendar,& SimpleDateFormat

Joda-Time项目,现在在maintenance mode,建议迁移到java.time类。请参阅Oracle Tutorial。并搜索堆栈溢出了很多例子和解释。规格是JSR 310

你可调换java.time直接对象与数据库。使用符合JDBC 4.2或更高版本的JDBC driver。无需字符串,不需要java.sql.*类。

从何处获取java.time类?

ThreeTen-Extra项目与其他类扩展java.time。这个项目是未来可能增加java.time的一个试验场。您可以在这里找到一些有用的类,如Interval,YearWeek,YearQuartermore

相关问题