Java 转换时区

Java convert time zone

在 Java 7 中,保存具有明确时区的 DateTime 并将其转换为不同时区的最佳方法是什么。

当我说转换时,时间(可能还有日期)被转换为时区和转换到的时区之间的差异。所以从PST转换成EST,不仅仅是对象中的时区变成了EST,而是时间部分增加了3小时,可能导致日期翻转1天。

我必须处理的是toLocalTime() 和toUtcTime()。我更希望能够处理转换到任何时区。

tl;博士

ZonedDateTime.now(                      // Capture the current moment as seen with a wall-clock time used by the people of a certain region (a time zone). 
    ZoneId.of( "America/Los_Angeles" )  // Use proper time zone names in `continent/region` format. Never use pseudo-zones such as `PST` & `EST`.
).withZoneSameInstant(                  // Adjust from one zone to another. Using immutable objects, so we produce a second distinct `ZonedDateTime` object.
    ZoneId.of( "America/New_York" )     // Same moment, different wall-clock time.
)

java.time & ThreeTen-Backport

要在 Java 7 中获得大部分 java.time 功能,请添加 ThreeTen-Backport 库到您的项目。

通常最好使用 UTC 值。

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

仅在 business logic 需要或向用户显示时应用时区。

您的 PSTEST 值是 而不是 实际时区。使用 proper time zone names.

ZoneId z = ZoneId.of( "America/Los_Angeles" ) ; 

应用于Instant to get a ZonedDateTime对象。同一时刻,时间轴上的同一点,不同的 wall-clock 时间。

ZonedDateTime zdt = instant.atZone( z ) ;  

调整到另一个时区。 java.time框架使用immutable objects。因此,我们不是改变(“变异”)原始对象,而是根据原始对象的值生成一个单独的不同对象。

ZonedDateTime 对象和 Instant 都代表同一时刻,时间轴上的同一点。这是在 date-time 处理中理解的一个重要概念。想象两个人,一个在北美西海岸,一个在北美东海岸,在 phone 上互相交谈。如果他们同时抬头看挂在各自墙上的时钟,他们看到的时间是几点?同样的时刻,不同的 wall-clock 时间。

ZoneId zNewYork = ZoneId.of( "America/New_York" ) ;
ZonedDateTime zdtNewYork = zdt.withZoneSameInstant( zNewYork ) ;  // Same moment, different wall-clock time.

所有这些都已在 Stack Overflow 上多次提及。所以搜索更多的例子和讨论。


关于java.time

java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

Joda-Time project, now in maintenance mode, advises migration to the java.time 类.

要了解更多信息,请参阅 Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310

您可以直接与数据库交换 java.time 对象。使用 JDBC driver compliant with JDBC 4.2 或更高版本。不需要字符串,不需要 java.sql.* 类.

在哪里获取java.time类?

  • Java SE 8, Java SE 9,及以后
    • Built-in。
    • 标准 Java API 的一部分,带有捆绑实施。
    • Java 9 添加了一些小功能和修复。
  • Java SE 6 and Java SE 7
    • java.time 的大部分功能是 back-ported 到 Java ThreeTen-Backport 中的 6 和 7。
  • Android
    • Android 的更高版本 java.time 类 的捆绑实施。
    • 对于较早的 Android (<26),ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See

ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.