如何在Joda Time/Java 8中列出时区偏移量,时区ID和长名称?

Tin*_*iny 10 java timezone jodatime java-8 java-time

Joda Time的时区ID可以使用以下代码段显示.

Set<String> zoneIds = DateTimeZone.getAvailableIDs();

for(String zoneId:zoneIds) {
    System.out.println(zoneId);
}
Run Code Online (Sandbox Code Playgroud)

但是如何显示相应的时区偏移量,时区ID和长名称,以便列表看起来如下所示?

(GMT-10:00) Pacific/Honolulu, Hawaii Standard Time
(GMT-10:00) Pacific/Johnston, Hawaii Standard Time
(GMT-10:00) Pacific/Fakaofo, Tokelau Time
(GMT-10:00) HST, Hawaii Standard Time
Run Code Online (Sandbox Code Playgroud)

需要将它们列在下拉框中以供选择.


以下代码段显示了名称,但显示的偏移看起来很糟糕.

Set<String> zoneIds = DateTimeZone.getAvailableIDs();

for (String zoneId : zoneIds) {
    int offset = DateTimeZone.forID(zoneId).getOffset(new DateTime());
    String longName = TimeZone.getTimeZone(zoneId).getDisplayName();

    System.out.println("(" + offset + ") " + zoneId + ", " + longName);
}
Run Code Online (Sandbox Code Playgroud)

在它显示的长列表中,其中一些显示为,

(-36000000) Pacific/Honolulu, Hawaii Standard Time
(-36000000) Pacific/Johnston, Hawaii Standard Time
(-36000000) Pacific/Fakaofo, Tokelau Time
(-36000000) HST, Hawaii Standard Time
Run Code Online (Sandbox Code Playgroud)

偏移量应如此列表中所示.

Tin*_*iny 21

以下方法有效.

import java.util.Set;
import java.util.TimeZone;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

Set<String> zoneIds = DateTimeZone.getAvailableIDs();
DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("ZZ");

for (String zoneId : zoneIds) {
    String offset = dateTimeFormatter.withZone(DateTimeZone.forID(zoneId)).print(0);
    String longName = TimeZone.getTimeZone(zoneId).getDisplayName();

    System.out.println("(" + offset + ") " + zoneId + ", " + longName);
}
Run Code Online (Sandbox Code Playgroud)

我现在还没有意识到其他可能更好的方法.


要么

import java.util.Set;
import org.joda.time.DateTimeUtils;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

Set<String> zoneIds = DateTimeZone.getAvailableIDs();
DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("ZZ");

for (String zoneId : zoneIds) {
    String offset = dateTimeFormatter.withZone(DateTimeZone.forID(zoneId)).print(0);
    String longName = DateTimeZone.forID(zoneId).getName(DateTimeUtils.currentTimeMillis());

    System.out.println("(" + offset + ") " + zoneId + ", " + longName);
}
Run Code Online (Sandbox Code Playgroud)

对于格林威治标准时间(Etc/GMT+0例如),它将显示,例如,+00:00而不是GMT+00:00像第一种情况那样显示.

如果该名称不适用于语言环境,则此method(public final String getName(long instant))将返回格式为[+ - ] hh:mm的字符串.

Locale如果需要使用重载方法,也可以使用适当的方法,

public String getName(long instant, Locale locale)
Run Code Online (Sandbox Code Playgroud)

短名称,例如协调世界时的UTC,可以显示如下.

import java.util.Set;
import org.joda.time.DateTimeUtils;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

Set<String> zoneIds = DateTimeZone.getAvailableIDs();
DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("ZZ");

for (String zoneId : zoneIds) {
    String offset = dateTimeFormatter.withZone(DateTimeZone.forID(zoneId)).print(0);
    String shortName = DateTimeZone.forID(zoneId).getShortName(DateTimeUtils.currentTimeMillis());

    System.out.println("(" + offset + ") " + zoneId + ", " + shortName);
}
Run Code Online (Sandbox Code Playgroud)

用适当的Locale,如果使用重载方法需要,

public String getShortName(long instant, Locale locale)
Run Code Online (Sandbox Code Playgroud)

更新:

使用Java SE 8中的Java Time API进一步简化了这一过程.

import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.TextStyle;
import java.util.Locale;
import java.util.Set;

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

for (String zoneId : zoneIds) {
    ZoneId zone = ZoneId.of(zoneId);
    ZonedDateTime zonedDateTime = ZonedDateTime.now(zone);

    ZoneOffset offset = zonedDateTime.getOffset();
    String longName = zone.getDisplayName(TextStyle.FULL, Locale.ENGLISH);

    System.out.println("(" + offset + ") " + zoneId + ", " + longName);
}
Run Code Online (Sandbox Code Playgroud)

显示名称有多种样式可供选择java.time.format.TextStyle.例如,可以使用显示缩写TextStyle.SHORT.

zone.getDisplayName(TextStyle.FULL, Locale.ENGLISH)将显示像"印度时间"这样的长名字.然而,与Joda Time不同,这不是一个全名.

以下内容将显示给定名称的全名,如"India Standard Time"(如果适用).

DateTimeFormatter pattern = DateTimeFormatter.ofPattern("zzzz");
String longName = pattern.format(ZonedDateTime.now(ZoneId.of(zoneId)));
Run Code Online (Sandbox Code Playgroud)

以下将显示给定区域的区域偏移量GMT+05:30(注意模式的大小写).

DateTimeFormatter pattern = DateTimeFormatter.ofPattern("ZZZZ");
String longName = pattern.format(ZonedDateTime.now(ZoneId.of(zoneId)));
Run Code Online (Sandbox Code Playgroud)

以下是显示缩写.

DateTimeFormatter pattern = DateTimeFormatter.ofPattern("zzz");
String longName = pattern.format(ZonedDateTime.now(ZoneId.of(zoneId)));
Run Code Online (Sandbox Code Playgroud)

ZZZ区域偏移的资本,如+0530,+0000.

https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html