os时区更改tomcat需要重启
我的Web应用程序在Apache Tomcat 7.0上运行。 我们调用java util calendar来获取服务器的日期时间。 问题是,如果更改了系统时区,则java日历将继续运行“旧”时区的日期时间。
Tomcat使用的JDK是 – JDk1.6
您能否告诉我们为什么tomcat需要重启以反映新的时区?
最好的方法是在Java中使用日期时始终指定时区。 或者在tomcat中指定
-Duser.timezone = GMT
参数。 其他方式Tomcat在启动时从系统加载时区。
TL;博士
尽可能使用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.time类完全取代。
您能否告诉我们为什么tomcat需要重启以反映新的时区?
我猜你的网络应用程序不适当地缓存来自UTC的偏移而不是总是使用时区。 与UTC的偏移量仅为UTC的几小时 – 分钟 – 秒。 时区更多,是特定地区人民使用的偏移的过去,现在和未来变化的历史。 因此,始终使用时区而不是仅仅偏移。 有关详细信息,请参阅我对类似问题的回答 。
以continent/region
的格式指定适当的时区名称 ,例如America/Montreal
, Africa/Casablanca
或Pacific/Auckland
。 切勿使用3-4字母缩写,例如EST
或IST
因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
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思考,工作,记录,存储和交换数据。 在作为程序员或管理员工作时忘记自己的教区时区。
Instant
类表示UTC时间轴上的一个时刻,分辨率为纳秒 (最多九(9)位小数)。
Instant instant = Instant.now() ; // Capture current moment in UTC.
关于java.time
java.time框架内置于Java 8及更高版本中。 这些类取代了麻烦的旧遗留日期时间类,如java.util.Date
, Calendar
和SimpleDateFormat
。
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
要了解更多信息,请参阅Oracle教程 。 并搜索Stack Overflow以获取许多示例和解释。 规范是JSR 310 。
您可以直接与数据库交换java.time对象。 使用符合JDBC 4.2或更高版本的JDBC驱动程序 。 不需要字符串,不需要java.sql.*
类。
从哪里获取java.time类?
- Java SE 8 , Java SE 9及更高版本
- 内置。
- 带有捆绑实现的标准Java API的一部分。
- Java 9增加了一些小function和修复。
- Java SE 6和Java SE 7
- 许多java.timefunction都被反向移植到ThreeTen-Backport中的 Java 6和7。
- Android的
- 更高版本的Android捆绑java.time类的实现。
- 对于早期的Android(<26), ThreeTenABP项目采用ThreeTen-Backport (如上所述)。 请参见如何使用ThreeTenABP ….
ThreeTen-Extra项目使用其他类扩展了java.time。 该项目是未来可能添加到java.time的试验场。 您可以在这里找到一些有用的课程,如Interval
, YearWeek
, YearQuarter
等。
我想需要重新启动的原因是没有人在为他们积极运行并连接到互联网时通过不同时区的服务器提供服务。 有趣的用例。 显然很少见。 极少。
将您的服务器设置为UTC,使用UTC启动tomcat,然后配置您的应用程序以在您碰巧感兴趣的任何时区格式化时间 – 问题已解决。