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

标签 java timezone java-8 jodatime java-time

Joda Time 的时区 ID 可以简单地用以下代码段显示。

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

for(String zoneId:zoneIds) {
    System.out.println(zoneId);
}

但是如何显示相应的时区偏移、时区 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

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


以下代码片段显示了名称,但它显示的偏移量看起来很不稳定。

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

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

(-36000000) Pacific/Honolulu, Hawaii Standard Time
(-36000000) Pacific/Johnston, Hawaii Standard Time
(-36000000) Pacific/Fakaofo, Tokelau Time
(-36000000) HST, Hawaii Standard Time

偏移量应如this中所示列表。

最佳答案

以下方法有效。

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

可能还有其他我现在还不知道的可能更好的方法。


或者

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

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

If the name is not available for the locale, then this method (public final String getName(long instant)) returns a string in the format [+-]hh:mm.

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

public String getName(long instant, Locale locale)

短名称,例如协调世界时的 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);
}

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

public String getShortName(long instant, Locale locale)

更新:

使用 Java Time API在 Java SE 8 中进一步简化了这一点。

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

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

zone.getDisplayName(TextStyle.FULL, Locale.ENGLISH) 将显示长名称,如“印度时间”。然而,与 Joda Time 不同,这不是全名。

以下将显示给定名称的全名,如“印度标准时间”(如果适用)。

DateTimeFormatter pattern = DateTimeFormatter.ofPattern("zzzz");
String longName = pattern.format(ZonedDateTime.now(ZoneId.of(zoneId)));

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

DateTimeFormatter pattern = DateTimeFormatter.ofPattern("ZZZZ");
String longName = pattern.format(ZonedDateTime.now(ZoneId.of(zoneId)));

下面是显示缩写。

DateTimeFormatter pattern = DateTimeFormatter.ofPattern("zzz");
String longName = pattern.format(ZonedDateTime.now(ZoneId.of(zoneId)));

大写 ZZZ 用于区域偏移,例如 +0530+0000

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

关于java - 如何在 Joda Time/Java 8 中列出时区偏移量、时区 ID 和长名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15967642/

相关文章:

java - 如何一步获取子类对象?

java - Google Guice - 类必须有一个(且只有一个)用 @Inject 注释的构造函数或非私有(private)的零参数构造函数

python - 如何处理 CMS 中的时区?

java - 检查目录中是否存在文件

java - 关闭流而不将其分配给变量 [Java]

java - 记录 selenium 测试并从 Java 运行它们

java - Java 运行时环境 : SIGSEGV (0xb) 检测到 fatal error

c++ - tzdb_list 有什么用

ios - 为什么 'Z' 在从 UTC 转换为 BST 时处于日期结束?

datetime - Java 8 LocalDateTime ZonedDateTime 无法解析带时区的日期