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

时间:2017-05-06 12:05:05

标签: java date timezone zoneinfo

我用utc格式的serva时区字符串,例如“UTC + 08:00”,“UTC-05:00”,问题是如何将这些utc格式字符串转换为TimeZone对象(java.util) .Time中的.TimeZone)

我试图通过zoneId进行如下转换,但不起作用:

ZoneId zoneId = ZoneId.of("UTC+08:00");
TimeZone timeZone = TimeZone.getTimeZone(zoneId);

我知道TimeZone timeZone = TimeZone.getTimeZone("Asia/Shanghai");可行,但我不知道“UTC + 08:00”和“亚洲/上海”之间的映射

2 个答案:

答案 0 :(得分:3)

TL;博士

  • 使用TimeZone类(现在是遗产)。
  • 改为使用ZoneOffsetZoneId

示例:

ZoneOffset.of( "+08:00" )

使用java.time.ZoneId,而不是TimeZone

与最早版本的Java捆绑在一起的麻烦的旧日期时间类现在已经遗留下来,取而代之的是java.time类。在这些旧的遗留类中,TimeZone已被ZoneIdZoneOffset取代。

offset-from-UTC是在UTC之前或之后调整的小时数和分钟数。这由ZoneOffset类表示。

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

使用时区始终优先于偏移,因为区域具有偏移量以及更多信息。但是你的例子只是补偿。因此,在删除字符ZoneOffset后,使用UTC来解析字符串。

String input = "UTC+08:00".replace( "UTC" , "" ) ;
ZoneOffset offset = ZoneOffset.of( input ) ;

不要猜测时区

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

例如,+08:00的偏移量。该偏移量目前由several different time zones使用,包括Asia/ShangaiAsia/MacaoAustralia/Perth

如果您某些特定区域用于日期时间值,请应用它以获得ZonedDateTime。但不要猜。

Instant类表示UTC时间轴上的一个时刻,分辨率为纳秒。

Instant instant = Instant.now() ;
ZoneId z = ZoneId.of( "Asia/Shanghai" ) ; 
ZonedDateTime zdt = instant.atZone( z ) ;

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

Instant instant = Instant.now() ;
ZoneOffset offset = ZoneOffset.of( "+08:00" ) ; 
OffsetDateTime odt = instant.atOffset( offset ) ;

转换

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

TimeZone myLegacyTimeZone = TimeZone.getTimeZone( myModernZoneId ); 

......和......

ZoneId z = myLegacyTimeZone.toZoneId() ;

请注意ZoneOffsetZoneId的子类。通常,我们忽略了继承关系。如果您只有+08:00这样的偏移,请使用ZoneOffset。如果您有Asia/Shanghai等完整时区,请使用ZoneId。此规则的一个例外是此转换为/ TimeZone,其中只识别超类ZoneId

答案 1 :(得分:2)

如果您删除UTC,则可以将其解析为ZoneOffset,这会扩展ZoneId

ZoneId zoneId = ZoneOffset.of("+08:00")