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

deH*_*aar 4 java timezone java-time zoneddatetime

不久前,我回答了一个关于如何从ZonedDateTime解析的String.
它一般有效,但在 OP 的系统和我的系统上有相同代码的不同输出,不知何故不再让我离开。

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

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

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

这怎么可能?系统默认语言环境对解析'z'in datetime有什么影响String吗?

这是我在问题中的回答的代码加上我的输出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());
}
Run Code Online (Sandbox Code Playgroud)

它的输出是这样的:

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());
}
Run Code Online (Sandbox Code Playgroud)

任何人都可以指出我犯的错误或确认并解释不同系统默认值ZoneId对解析 aString到 a 的影响ZonedDateTime吗?

Ole*_*.V. 5

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

您可以通过重载DateTimeFormatterBuilder.appendZoneText(TextStyle, Set<ZoneId>)方法在不明确的情况下控制时区的选择。

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