tl;博士
世界标准时间:
Instant.now() // Instantiate an object capturing the current moment in UTC.
.toString() // Generate a String representing textually that date-time value using standard ISO 8601 format.
2018-03-16T00:57:34.233762Z
分区:
ZonedDateTime.now( ZoneId.of( "Africa/Tunis" ) ) // Instantiate an object representing the current moment with a wall-clock time seed by people in a particular region (time zone).
.toString() // Generate a String representing textually that date-time value using standard ISO 8601 format wisely extended to append the name of the time zone in square brackets.
2018-03-16T01:57:34.233762+01:00[非洲/突尼斯]
详情
Answer by Shailendra 准确无误。
此外,问题中看到的Date 类是麻烦的旧日期时间类的一部分,这些类现在已成为遗留问题,完全被 java.time 类所取代。
java.util.Date 的替换是 java.time.Instant。 Instant 类代表UTC 时间线上的时刻,分辨率为nanoseconds(最多九 (9) 位小数)。
Instant::toString ➞ UTC 始终
当调用遗留类的 Date::toString 方法时,其作者选择的不幸行为是动态应用 JVM 当前的默认时区。这不会造成混乱。幸运的是,现代类在没有添加任何时区的情况下说出了一个简单的事实:Instant 始终采用 UTC。
Instant.now().toString()
2018-03-16T00:57:34.233762Z
字符串格式是标准的ISO 8601 格式。末尾的Z 是Zulu 的缩写,意思是UTC。
CEST 时区时间
不存在名为CEST 的时区。这样的3-4 letter names 是伪区域。它们没有标准化。它们不是唯一的(!)。而是使用proper time zone 格式为continent/region。
ZoneId z = ZoneId.of( "Europe/Paris" ) ;
您可以通过将ZoneId 应用于您的Instant 来获得ZoneDateTime,从而将UTC 调整为这样的时区。
Instant instant = Instant.now() ;
ZonedDateTime zdt = instant.atZone( z ) ;
zdt.toString(): 2018-03-16T01:57:34.233762+01:00[欧洲/巴黎]
或使用快捷方式ZonedDateTime.now。
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
您也可以将ZonedDateTime 调整到另一个时区。注意 java.time 使用immutable objects。因此,在调整的过程中,我们得到了一个基于原始对象但又不干扰原始对象的新对象。
ZoneId zNewYork = ZoneId.of( "America/New_York" ) ;
ZonedDateTime zdtNewYork = zdt.withZoneSameInstant( zNewYork ) ;
zdtNewYork.toString(): 2018-03-15T20:57:34.233762-04:00[America/New_York]
非常清楚instant、zdt 和zdtNewYork 是三个独立的对象,它们代表同一时刻,即时间轴上的同一点。同一时刻,不同的挂钟时间。
我在美国的 Ubuntu 服务器上运行了一个 Java 应用程序并配置了 CEST 时区
仅供参考,一般来说,服务器默认时区的最佳做法是 UTC。
更重要的是,您的服务器操作系统和 JVM 的当前默认时区应该与您的 Java 应用程序无关。
与其隐式依赖 JVM 当前的默认时区,不如始终明确指定所需/预期的时区。将可选的 ZoneId 参数传递给各种 java.time 方法,如上面的代码所示。
(顺便说一句,Locale 也是如此 - 始终指定所需/预期的语言环境,而不是隐式依赖当前默认值。)
关于java.time
java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.Date、Calendar 和 SimpleDateFormat。
Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。
要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。
您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。
从哪里获得 java.time 类?
ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如Interval、YearWeek、YearQuarter 和more。