ZonedDateTime 正确解析模式“O”中的“GMT”区域,但不能解析“UTC”

Lei*_*n C 4 java java-time zoneddatetime datetimeformatter java-17

以下正确解析文本输入“2022-12-29 01:16:03 GMT+08:00”。

public ZonedDateTime parseZonedDateTime(String timeStr) {
  DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss O");

  ZonedDateTime zonedDateTime = ZonedDateTime.parse(timeStr, dtf);

  return zonedDateTime;
}
Run Code Online (Sandbox Code Playgroud)

但是,如果输入字符串是“2022-12-29 01:16:03 UTC-08:00”,ZonedDateTime.parse() 方法会抛出异常

java.time.format.DateTimeParseException: Text '2022-12-29 01:16:03 UTC-08:00' could not be parsed at index 20
Run Code Online (Sandbox Code Playgroud)

请访问 Ideone.com 查看在 Java 12 上运行的代码。

根据 DateTimeFormatter 文档,https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html

“GMT+08:00”和“UTC-08:00”都被视为本地化区域偏移“O”。

正确的模式应该是什么,以便解析器接受 GMT 和 UTC 输入?

我尝试使用格式“yyyy-MM-dd HH:mm:ss OOOO”,但行为是相同的。

有一个类似的问题为什么“GMT+8”无法用模式“O”解析,尽管直接从文档中复制出来?据此,该错误已在 Java 9 build b116 中修复。

不过我正在使用 java 17.0.4.1-librca

Arv*_*ash 5

正确的模式应该是什么,以便解析器接受 GMT 和 UTC 输入?

使用V而不是O使用模式,yyyy-MM-dd HH:mm:ss VV

演示

public class Main {
    public static void main(String args[]) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss VV", Locale.ENGLISH);
        Stream.of(
                "2022-12-29 01:16:03 GMT+08:00",
                "2022-12-29 01:16:03 UTC-08:00"
            )
            .map(s -> ZonedDateTime.parse(s, dtf))
            .forEach(System.out::println);
        ;
    }
}
Run Code Online (Sandbox Code Playgroud)

输出

2022-12-29T01:16:03+08:00[GMT+08:00]
2022-12-29T01:16:03-08:00[UTC-08:00]
Run Code Online (Sandbox Code Playgroud)

Online Demo

从Trail: Date Time中了解有关现代日期时间 API 的更多信息。

  • @LeilJanC 我建议您教育数据发布者仅使用 [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) 标准格式。我建议始终扩展偏移量以使用填充零,并使用小时和分钟。并且不要插入“UTC”或“GMT”。因此,不要使用“UTC-5”,而是使用“-05:00”。虽然 ISO 8601 允许在偏移量中仅缩短小时数,但我发现多个图书馆不接受此类输入。最好使用扩展格式。示例: `OffsetDateTime.parse( "2022-12-29T01:16:03+08:00" )` — 简单。 (3认同)
  • @LeilJanC - 不幸的是,当谈到日期解析时,没有什么比“一刀切”更好的了。您可以使用也适用于此变体的“DateTimeFormatterBuilder”定义“DateTimeFormatter”。如果您需要帮助,请告诉我,我将发布更新。 (2认同)