解析ZonedDateTime.parse忽略偏移量

时间:2019-07-12 13:03:20

标签: java date zoneddatetime java.time

我正在尝试使用22/04/17 09:24:28 UTC+01格式解析dd/MM/yy HH:mm:ss zX-但无论偏移量如何,创建的ZonedDateTime都是相同的。

下面是重现此示例的示例,其中我以编程方式更改了偏移量:

final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yy HH:mm:ss zX")
    .withZone(ZoneId.systemDefault());

System.out.println(MessageFormat.format("Current time is \"{0}\"", formatter.format(Instant.now())));

for (int i = 1; i <= 12; i++) {
    final String str = String.format("22/04/17 09:24:28 UTC+%02d", i);
    System.out.println(MessageFormat.format("Parsed String \"{0}\", got result of \"{1}\"", str,
        ZonedDateTime.parse(str, formatter)));

}

输出:

Current time is "12/07/19 12:59:25 ZZ"
Parsed String "22/04/17 09:24:28 UTC+01", got result of "2017-04-22T09:24:28Z[UTC]"
Parsed String "22/04/17 09:24:28 UTC+02", got result of "2017-04-22T09:24:28Z[UTC]"
Parsed String "22/04/17 09:24:28 UTC+03", got result of "2017-04-22T09:24:28Z[UTC]"
Parsed String "22/04/17 09:24:28 UTC+04", got result of "2017-04-22T09:24:28Z[UTC]"
Parsed String "22/04/17 09:24:28 UTC+05", got result of "2017-04-22T09:24:28Z[UTC]"
Parsed String "22/04/17 09:24:28 UTC+06", got result of "2017-04-22T09:24:28Z[UTC]"
Parsed String "22/04/17 09:24:28 UTC+07", got result of "2017-04-22T09:24:28Z[UTC]"
Parsed String "22/04/17 09:24:28 UTC+08", got result of "2017-04-22T09:24:28Z[UTC]"
Parsed String "22/04/17 09:24:28 UTC+09", got result of "2017-04-22T09:24:28Z[UTC]"
Parsed String "22/04/17 09:24:28 UTC+10", got result of "2017-04-22T09:24:28Z[UTC]"
Parsed String "22/04/17 09:24:28 UTC+11", got result of "2017-04-22T09:24:28Z[UTC]"
Parsed String "22/04/17 09:24:28 UTC+12", got result of "2017-04-22T09:24:28Z[UTC]"

请注意,无论偏移量如何,结果都是相同的。

1 个答案:

答案 0 :(得分:1)

在您的字符串中,我将UTC+01设为UTC的+1小时偏移量。因此,尽管UTC可能被解释为时区(实际上不是),但此处无关紧要,因为您字符串中的时间不是UTC,而是UTC + 01:00。因此,我们不应使用时区名称z进行解析。这样做基本上是给您错误的结果的原因(结合解析为ZonedDateTime)。

@VGR在他/她的评论中是正确的:我们想要'UTC'x。我仅使用两个示例,足以说明它们给出了不同的结果。

    final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yy HH:mm:ss 'UTC'x");

    String str = "22/04/17 09:24:28 UTC+01";
    System.out.println(MessageFormat.format("Parsed String \"{0}\", got result of \"{1}\"",
            str, OffsetDateTime.parse(str, formatter)));
    str = "22/04/17 09:24:28 UTC+07";
    System.out.println(MessageFormat.format("Parsed String \"{0}\", got result of \"{1}\"",
            str, OffsetDateTime.parse(str, formatter)));

输出为:

Parsed String "22/04/17 09:24:28 UTC+01", got result of "2017-04-22T09:24:28+01:00"
Parsed String "22/04/17 09:24:28 UTC+07", got result of "2017-04-22T09:24:28+07:00"

UTC周围的单引号表示文字文本,因此格式化程序会检查该文字是否存在,但不对其赋予任何意义。一个x的偏移量仅由小时组成(除非非零分钟是偏移量的一部分),例如+01+12。由于您的字符串包含偏移量且没有时区(例如,欧洲/伦敦表示英国时间),因此OffsetDateTime是代表日期和时间的(最正确的)类型。

后退一步,虽然您的格式是完全可读的,但是它不是标准的,也不适合用于计算机解析。您可能需要考虑是否可以说服字符串的发送者使用ISO 8601格式,例如2017-04-22T09:24:28+01:00

链接:Wikipedia article: ISO 8601