java - 日期时间字符串中的 'z' 在不同的语言环境中是否有不同的输出?

标签 java timezone zoneddatetime java-time

不久前,我提供了一个关于如何从 ZonedDateTime 中提取时区的问题的答案,该ZonedDateTime 是从 String 解析的。
它总体上有效,但在 OP 的系统和我的系统上,相同代码的输出不同,这不知何故不再让我离开。

The related question问如何从 ZonedDateTime 获取 ZoneId,我提供了一种方法。诚然,这不是公认的答案,但似乎仍然值得某人点赞。

我的回答的特别之处在于用于解析时间 String 的模式中的 'z'String 中有一个时区名称,表示 "Australia/Adelaide" by "... ACST"(澳大利亚中部标准时间).

当我在我的系统上解析它并使用 DateTimeFormatter.ISO_ZONED_DATE_TIME 打印/格式化 ZonedDateTime 时,它会在 "America/Manaus"< 中打印时间 并提取了 ZoneId,它仍然是来自南美洲的那个。 OP 在我的回答下方的评论中指出,在他的系统上,至少有一个输出行显示了所需/正确的 ZoneId

这怎么可能?系统默认语言环境是否对解析日期时间 String 中的 'z' 有任何影响?

这是我在问题中的回答中的代码加上我的 ZoneId.systemDefault() 的输出:

public static void main(String args[]) throws Exception {
    String time = "2 Jun 2019 03:51:17 PM ACST";
    String pattern = "d MMM yyyy hh:mm:ss a z"; // z detects the time zone (ACST here)
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);

    // parse a time object using the formatter and the time String
    ZonedDateTime zdt = ZonedDateTime.parse(time, formatter);
    // print it using a standard formatter
    System.out.println(zdt.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
    // extract the zone id
    ZoneId zoneId = zdt.getZone();
    ZoneId sysDefault = ZoneId.systemDefault();
    // print the zone id
    System.out.println("Time zone of parsed String is " + zoneId);
    System.out.println("System default time zone is " + sysDefault);

    // retrieve the instant seconds
    Instant instant = zdt.toInstant();
    // print the epoch seconds of another time zone
    System.out.println("Epoch seconds in Australia/Adelaide are " 
            + instant.atZone(ZoneId.of("Australia/Adelaide")).toEpochSecond());
}

它的输出是这样的:

2019-06-02T15:51:17-04:00[America/Manaus]
Time zone of parsed String is America/Manaus
System default time zone is Europe/Berlin
Epoch seconds in Australia/Adelaide are 1559505077

谁能指出我犯过的错误或确认并解释不同系统默认 ZoneId 对将 String 解析为 ZonedDateTime< 的影响?

最佳答案

我也遇到过在不同的 JVM 上解析不明确的时区缩写(在提供语言环境时也是如此,所以这不是唯一的问题)。我认为没有记录确切的行为。在某些情况下,选择了 JVM 的默认时区,但我不知道它是否总是匹配。

您可以通过重载 DateTimeFormatterBuilder.appendZoneText(TextStyle, Set<ZoneId>) 来控制模棱两可情况下的时区选择。方法。

区域设置不同的示例:欧洲/柏林和许多其他欧洲时区将被格式化为 Central European TimeCET在许多地方。在德语语言环境中,它们变成了 Mitteleuropäische ZeitMET .

关于java - 日期时间字符串中的 'z' 在不同的语言环境中是否有不同的输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57267795/

相关文章:

java - 在 spring boot 中运行多个 Tomcat 实例?

深入 Java SSH2 库 : Trilead/Ganymed/Orion [/other?]

城市和州或国家/地区的 Python 当前时间

java - 为 IntelliJ Cassandra Database Viewer 设置时区

Java SimpleDateFormat.getTimeZone().getID() 返回 Asia/Jerusalem 而不是 Asia/Kolkata

java - 如何将 TIMESTAMP 列映射到 ZonedDateTime JPA 实体属性?

java - 当 jtable 中存在空值时,如何分隔要动态添加到 jtable 中的行数据?

java - 组合框不使用 setCellFactory 添加元素

java - 如何在Java 1.6中将UTC日期转换为本地日期

在夏令时结束时创建 Java 8 ZonedDateTime 实例