在 Java 中使用给定时刻的特定偏移量获取时区

问题描述 投票:0回答:1

我知道:

  • 偏移量只是 UTC 时间子午线之前/之后的小时数、分钟数、秒数。
  • 时区是特定地区人民使用的偏移量的过去、现在和未来变化的命名历史,由其政客决定。

因此,对于任何时刻,特定时区都使用一个偏移量,而在另一个时刻,同一时区可能使用不同的偏移量。

当然,任意数量的时区可能在任意一个时间点共享相同的偏移量。

有没有办法在特定时刻使用特定偏移量来获取时区列表?

java timezone java-time timezone-offset
1个回答
0
投票

是的,您可以使用 java.time 类在 Java 8+ 中获取这样的列表。

ZoneId
类代表每个时区,名称格式为
Continent/Region
。每个时区使用的规则包含在
ZoneRules
对象中。

ZoneOffset
类仅代表一个偏移量。

Instant
类表示一个时刻,即时间线上的特定点,如与 UTC 零小时-分钟-秒的偏移量所示。要获取当前时刻,请致电
Instant.now()

我们可以询问区域规则以了解区域在任何特定时刻使用的偏移量。这意味着通过名称获取

ZoneId
,询问其规则,并将
Instant
传递给规则对象的
getOffset
方法。

注意:政客经常更改其管辖范围内的时区规则。他们有时会在毫无预警的情况下做出这些改变。确保 JVM 中的 tzdata 是您感兴趣的时区的最新数据。 您可能需要自己更新 tzdata,因为新版本的到来速度比 Java 的更新速度更快。

final Instant now = Instant.now ( );
final ZoneOffset offsetTarget = ZoneOffset.ofHours ( -4 );  // -04:00

final Set < String > zoneNames = ZoneId.getAvailableZoneIds ( );
final Collection < ZoneId > zoneIdsWithTargetOffset = new ArrayList <> ( );
for ( String zoneName : zoneNames )
{
    ZoneId zoneId = ZoneId.of ( zoneName );
    ZoneRules rules = zoneId.getRules ( );
    ZoneOffset offset = rules.getOffset ( now );
    if ( offset.equals ( offsetTarget ) )
    {
        zoneIdsWithTargetOffset.add ( zoneId );
    }
}
System.out.println ( "At " + now + ", " + zoneIdsWithTargetOffset.size ( ) + " zones have an offset of " + offsetTarget + " ➡️ " + zoneIdsWithTargetOffset ); // ️

请参阅此 在 Ideone.com 上运行的代码

在 2023-11-21T21:59:37.279097Z,43 个区域的偏移量为 -04:00 ➡️ [美洲/库亚巴、美洲/马里戈特、加拿大/大西洋、Etc/GMT+4、美洲/马瑙斯、美洲/St_Thomas , 美洲/安圭拉, 美洲/巴巴多斯, 美洲/库拉索, 美洲/圭亚那, 美洲/马提尼克, 美洲/波多黎各, 美洲/西班牙港, SystemV/AST4, 美洲/克拉伦代克, 美洲/安提瓜岛, 美洲/蒙克顿, 美洲/圣文森特, 美洲/多米尼克、大西洋/百慕大、巴西/西部、美洲/阿鲁巴、美洲/哈利法克斯、美洲/拉巴斯、美洲/布兰克-萨布隆、美洲/圣多明各、美洲/格莱斯_湾、美洲/圣巴泰勒米、美洲/圣卢西亚、美洲/蒙特塞拉特、美洲/Lower_Princes、America/Thule、America/Tortola、America/Porto_Velho、America/Campo_Grande、America/Goose_Bay、America/Virgin、America/Boa_Vista、America/Grenada、America/St_Kitts、America/Caracas、America/Guadeloupe、SystemV/AST4ADT ]

© www.soinside.com 2019 - 2024. All rights reserved.