如何在java中从时区偏移量中获取时区



我知道如何得到相反的结果。给定一个时区,我可以通过以下代码片段获得时区偏移:

TimeZone tz = TimeZone.getDefault();
System.out.println(tz.getOffset(System.currentTimeMillis()));

我想知道如何从时区偏移量中获取时区名称。

给定

timezone offset = 21600000(以毫秒为单位;+6.00偏移量)

我想得到以下任何可能的时区名称的结果:

(GMT+6:00) Antarctica/Vostok
(GMT+6:00) Asia/Almaty
(GMT+6:00) Asia/Bishkek
(GMT+6:00) Asia/Dacca
(GMT+6:00) Asia/Dhaka
(GMT+6:00) Asia/Qyzylorda
(GMT+6:00) Asia/Thimbu
(GMT+6:00) Asia/Thimphu
(GMT+6:00) Asia/Yekaterinburg
(GMT+6:00) BST
(GMT+6:00) Etc/GMT-6
(GMT+6:00) Indian/Chagos

tl;dr

Instant instant = Instant.now();
List < String > names =
        ZoneId
                .getAvailableZoneIds()
                .stream()
                .filter(
                        ( String name ) ->
                                ZoneId
                                        .of( name )
                                        .getRules()
                                        .getOffset( instant )
                                        .equals(
                                                ZoneOffset.ofHours( 6 )
                                        )
                )
                .collect( Collectors.toList() )
;

在Java 14.0.1:中

names=[Asia/Kashgar,Etc/GMT-6,Asia/阿拉木图,Asia/达卡,Asia/鄂木斯克,Asia/Dhaka,Indian/Chagos,Asia/Qostanay,Asia/Bishkek,Antarctic/Vostok,Asia/乌鲁木齐,Asia/Thimbu,Asia/廷布]

java.time

现代解决方案使用java.time类,这些类在几年前取代了糟糕的遗留日期-时间类。具体而言,TimeZone被替换为:

  • ZoneId
  • ZoneOffset
  • ZoneRules

与UTC的偏移量仅为本初子午线之前或之后的小时-分-秒。时区远不止这些。时区是特定地区人民使用的偏移量的过去、现在和未来变化的历史。时区的名称采用Continent/Region格式。请参阅分区列表。

获取JVM的当前时区。

ZoneId z = ZoneId.systemDefault() ;

获取当前定义的所有ZoneId对象的列表。请注意,政客们经常更改时区。因此,这个列表及其包含的规则将发生变化。保持tzdata的最新状态。

Set< String > zones = ZoneId.getAvailableZoneIds() ;

你问:

我想知道如何从时区偏移量中获取时区名称。

许多时区在任何给定时刻都可能巧合地共享相同的偏移量。在下面的代码中,我们循环所有已知的时区,询问每个时区的偏移量。

由于时区规则会随着时间的推移而变化(由政治家决定),您必须提供一个时刻,以便每个区域使用偏移量。这里我们在运行时使用当前时刻。

// Convert your milliseconds to an offset-from-UTC.
int milliseconds = 21_600_000;
int seconds = Math.toIntExact( TimeUnit.MILLISECONDS.toSeconds( milliseconds ) );
ZoneOffset targetOffset = ZoneOffset.ofTotalSeconds( seconds );
// Capture the current moment as seen in UTC (an offset of zero hours-minutes-seconds).
Instant now = Instant.now();
// Loop through all know time zones, comparing each one’s zone to the target zone.
List < ZoneId > hits = new ArrayList <>();
Set < String > zoneNames = ZoneId.getAvailableZoneIds();
for ( String zoneName : zoneNames )
{
    ZoneId zoneId = ZoneId.of( zoneName );
    ZoneRules rules = zoneId.getRules();
    // ZoneRules rules = zoneId.getRules() ;
    ZoneOffset offset = rules.getOffset( now );
    if ( offset.equals( targetOffset ) )
    {
        hits.add( zoneId );
    }
}

转储到控制台。请在IdeOne.com上实时查看此代码。

// Report results.
System.out.println( "java.version " + System.getProperty("java.version") ) ;
System.out.println( "java.vendor " + System.getProperty("java.vendor") ) ;
System.out.println() ;
System.out.println( "targetOffset = " + targetOffset );
System.out.println( "hits: " + hits );

请在IdeOne.com上实时查看此代码。

java.version 12.0.1

java.vendor Oracle Corporation

targetOffset=+06:00

点击次数:[Asia/Kashgar,Etc/GMT-6,Asia/阿拉木图,Asia/达卡,Asia/鄂木斯克,Asia/Dhaka,Indian/Chagos,Asia/Qyzylorda,Asia/Bishkek,Antarctic/Vostok,Asia/乌鲁木齐,Asia/Thimbu,Asia/廷布]


关于java.time

java.time框架构建在Java8及更高版本中。这些类取代了诸如java.util.DateCalendar和&CCD_ 10。

要了解更多信息,请参阅Oracle教程。并在Stack Overflow中搜索许多示例和解释。规范是JSR310。

现在处于维护模式的JodaTime项目建议迁移到java.Time类。

您可以直接与数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC驱动程序。不需要字符串,也不需要java.sql.*类。休眠5&JPA 2.2支持java.time.

从哪里获得java.time类?

  • Java SE 8Java SE 9Java SE 10爪哇SE 11及更高版本-标准Java API的一部分,具有捆绑实现。
    • Java 9添加了一些小功能和修复程序
  • Java SE 6Java SE 7
    • java.time的大部分功能都是后移植到Java6&7英寸ThreeTen背包
  • 安卓
    • java.time类的Android捆绑包实现的后续版本
    • 对于早期的Android(<26),ThreeTenABP项目适用于ThreeTen Backport(如上所述)。请参阅如何使用ThreeTenABP…

使用TimeZone#getAvailableIDs(int)

import java.util.*;
class Hello
{
   public static void main (String[] args) throws java.lang.Exception
   {
     TimeZone tz = TimeZone.getDefault();
     int offset = 21600000;
     String[] availableIDs = tz.getAvailableIDs(offset);
     for(int i = 0; i < availableIDs.length; i++) {
       System.out.println(availableIDs[i]);
     }
   }
}

相关内容

  • 没有找到相关文章

最新更新