java - 为什么时区与 java 中的 main 方法和表单 Web 应用程序不同

标签 java time timezone

我正在获取系统当前时区:

Calendar calendar = new GregorianCalendar();
TimeZone systemTimeZone = calendar.getTimeZone(); 
  1. 如果我从 Java main 方法运行,它会给出正确的系统时区。
  2. 如果我从网络应用程序(从 REST Web 服务)运行,它会提供 Asia/Irkutsk 作为时区。

但是这是错误的,为什么?

最佳答案

tl;博士

  • 使用java.time类。
  • 明确指定您想要/预期的时区。

示例:

ZonedDateTime                     // Represents a moment as seen through the wall-clock time used by the people of a particular region.
.now(                             // Capture the current moment as seen in this time zone.
    ZoneId.of( "Asia/Kolkata" )   // Real time zone names are in `Continent/Region` format. Never use 2-4 letter pseudo-zones such as `IST`, `EST`, or `CST`. 
)

通常最好在大部分工作中使用 UTC。

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

Table of date-time types in Java, both modern and legacy

详细信息

JVM保留默认时区。除非您指定,否则将隐式应用此默认值。

当您在本地运行 Java 应用程序时,会隐式应用本地 JVM 的当前默认时区。

当您运行 Java Web 应用程序时,将隐式应用 Servlet 容器的 JVM 的当前默认时区。

我建议您停止使用可怕的日期时间类,例如Calendar。这些现在已经成为遗留物,多年前已被 JSR 310 中定义的现代 java.time 类所取代。

我强烈建议始终指定您想要/预期的时区。默认区域超出了程序员的控制范围。系统管理员或 JVM 内任何应用程序中的任何其他代码都可以在应用程序运行时更改默认时区。

要捕获 UTC 中的当前时刻,请使用Instant

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

要捕获特定时区的当前时刻,请使用 ZonedDateTime

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
<小时/>

关于java.time

java.time框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧类 legacy日期时间类,例如 java.util.Date , Calendar , & SimpleDateFormat .

要了解更多信息,请参阅 Oracle Tutorial 。并在 Stack Overflow 上搜索许多示例和解释。规范为JSR 310 .

Joda-Time项目,现在位于 maintenance mode ,建议迁移到java.time类。

您可以直接与数据库交换java.time对象。使用JDBC driver符合JDBC 4.2或稍后。不需要字符串,不需要 java.sql.* 类。

从哪里获取java.time类?

ThreeTen-Extra项目通过附加类扩展了 java.time。该项目是 java.time future 可能添加的内容的试验场。您可能会在这里找到一些有用的类,例如 Interval , YearWeek , YearQuarter ,和more .

关于java - 为什么时区与 java 中的 main 方法和表单 Web 应用程序不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21826128/

相关文章:

java - 将表格拆分为几页

javascript - 使用 24 小时格式的小时列表填充数组

javascript获取系统时区的时间戳而不是UTC

Python:生成可用于 MySQL 的日期时间字符串

java - 将位图资源存储在静态变量中

java - Google Drive API Java 客户端库日志记录

datetime - 使用 NodaTime 将 UTC 日期时间字符串转换为 Zoned DateTime

postgresql - 如何在 PostgreSQL 中返回不同时区的当前日期

java - 如何使用 JodaTime 保留原始时区

java - Windows 和 Mac 上的时区