我如何将时区字符串转换为 Java 中的 TimeZone 对象?

Jia*_* Xu 4 java timezone date zoneinfo

我有几个 UTC 格式的时区字符串,例如"UTC+08:00", "UTC-05:00",问题是如何将这些 utc 格式字符串转换为java.util.TimeZoneJava格式的字符串?

我尝试ZoneId按如下方式转换,但没有奏效:

ZoneId zoneId = ZoneId.of("UTC+08:00");
TimeZone timeZone = TimeZone.getTimeZone(zoneId);
Run Code Online (Sandbox Code Playgroud)

我知道TimeZone timeZone = TimeZone.getTimeZone("Asia/Shanghai");会的工作,但我不知道之间的映射"UTC+08:00""Asia/Shanghai"

Bas*_*que 7

tl;博士

  • 千万不能使用TimeZone类(现在的传统)。
  • 使用ZoneOffsetZoneId代替。

例子:

ZoneOffset.of( "+08:00" )
Run Code Online (Sandbox Code Playgroud)

使用java.time.ZoneId,不TimeZone

与最早版本的 Java 捆绑在一起的麻烦的旧日期时间类现在是遗留的,被 java.time 类取代。在这些旧的遗留类中TimeZone,现在被ZoneId和取代ZoneOffset

一个偏移从-UTC是一个数字的小时和分钟调整超前或落后,UTC。这由ZoneOffset类表示。

时区是偏移的集合,在确定其挂钟时间使用的特定区域中的偏移变化的历史。这由ZoneId类表示。

使用时区总是优于偏移量,因为区域具有偏移量加上更多信息。但你的例子只是抵消。所以ZoneOffset在删除字符后使用来解析字符串UTC

String input = "UTC+08:00".replace( "UTC" , "" ) ;
ZoneOffset offset = ZoneOffset.of( input ) ;
Run Code Online (Sandbox Code Playgroud)

不要猜测时区

您不能假设特定的偏移量意味着特定的时区。许多区域可能在过去、现在或将来使用了特定的偏移量。所以你不应该猜测区域。

以 的偏移量为例+08:00。这种偏移是目前使用的几种不同的时区,包括Asia/ShangaiAsia/Macao,和Australia/Perth

如果您确定某个特定区域用于日期时间值,请应用它以获取ZonedDateTime. 但不要猜测。

Instant类表示UTC时间线与纳秒的分辨率上一会儿。

Instant instant = Instant.now() ;
ZoneId z = ZoneId.of( "Asia/Shanghai" ) ; 
ZonedDateTime zdt = instant.atZone( z ) ;
Run Code Online (Sandbox Code Playgroud)

如果您不确定预期的时区并且只有偏移量,请使用偏移量获取OffsetDateTime.

Instant instant = Instant.now() ;
ZoneOffset offset = ZoneOffset.of( "+08:00" ) ; 
OffsetDateTime odt = instant.atOffset( offset ) ;
Run Code Online (Sandbox Code Playgroud)

转变

最好避免旧的遗留类TimeZone。但是,如果您必须使用该类来处理尚未为 java.time 类更新的旧代码,则可以转换为/从ZoneId. 使用添加到旧类的新转换方法。

TimeZone myLegacyTimeZone = TimeZone.getTimeZone( myModernZoneId ); 
Run Code Online (Sandbox Code Playgroud)

…和…

ZoneId z = myLegacyTimeZone.toZoneId() ;
Run Code Online (Sandbox Code Playgroud)

请注意,它ZoneOffset是 的子类ZoneId。通常,我们会忽略这种继承关系。如果您只有诸如 之类的仅偏移量+08:00,请使用ZoneOffset. 如果您有完整的时区,例如Asia/Shanghai,请使用ZoneId. 此规则的一个例外是这种与TimeZoneZoneId识别超类的之间的转换。


flu*_*lup 2

如果剥离 UTC,则可以将其解析为 ZoneOffset,它扩展了 ZoneId

ZoneId zoneId = ZoneOffset.of("+08:00")
Run Code Online (Sandbox Code Playgroud)