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

时间:2016-05-12 10:58:04

标签: java calendar timezone timezone-offset gregorian-calendar

我知道如何相反。给出了一个时区,我可以通过以下代码片段来获得时区偏移量:

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

2 个答案:

答案 0 :(得分:2)

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中:

名称= [亚洲/喀什,其他/ GMT-6,亚洲/阿拉木图,亚洲/达卡,亚洲/鄂木斯克,亚洲/达卡,印度/查哥斯,亚洲/科斯塔纳伊,亚洲/比什凯克,南极洲/沃斯托克,亚洲/乌鲁木齐,亚洲/廷布,亚洲/廷布]

java.time

现代解决方案使用的是 java.time 类,该类在几年前取代了可怕的传统日期时间类。具体来说,TimeZone被替换为:

距UTC的偏移量仅在本初子午线之前或之后数小时-数分钟-秒。时区更多。时区是过去,现在和将来更改特定区域的人们使用的偏移量的历史。时区的名称为Continent/Region。参见list of zones

获取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 );
    }
}

转储到控制台。请参见此code run live at 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

热门节目:[亚洲/喀什,等/ GMT-6,亚洲/阿拉木图,亚洲/达卡,亚洲/鄂木斯克,亚洲/达卡,印度/查哥斯,亚洲/奇济洛达,亚洲/比什凯克,南极洲/沃斯托克,亚洲/乌鲁木齐,亚洲/廷布,亚洲/廷布]


关于 java.time

java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendarSimpleDateFormat

要了解更多信息,请参阅Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规范为JSR 310

Joda-Time项目(现在位于maintenance mode中)建议迁移到java.time类。

您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*类。 Hibernate 5和JPA 2.2支持 java.time

在哪里获取java.time类?

答案 1 :(得分:1)

使用TimeZone类的getAvailableIDs()

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