java.time.format.DateTimeParseException: 无法解析文本“2021-02-19T00:45:09.798Z”,在索引 23 处找到未解析的文本

zzz*_*137 4 java java-time

我是 Java 新手,我不明白我的日期解析有什么问题。我已经尝试了许多类似帖子的解决方案,阅读了 DateTimeFormatter 文档,但仍然卡住了。任何帮助表示赞赏。谢谢你。

代码

String date = "2021-02-19T00:45:09.798Z"
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSZ");
ZonedDateTime parsedDate = ZonedDateTime.parse(date, formatter);
Run Code Online (Sandbox Code Playgroud)

错误

java.time.format.DateTimeParseException: Text '2021-02-19T00:45:09.798Z' could not be parsed, unparsed text found at index 23
Run Code Online (Sandbox Code Playgroud)

我也尝试使用DateTimeFormatter.ofPattern(pattern).withZone(zone)并收到相同的错误。

Arv*_*ash 8

您不需要格式化程序来解析给定的日期时间字符串,因为它已经符合ZoneDateTime#parse预期的默认格式。

import java.time.ZonedDateTime;

public class Main {
    public static void main(String[] args) {
        String date = "2021-02-19T00:45:09.798Z";
        ZonedDateTime parsedDate = ZonedDateTime.parse(date);
        System.out.println(parsedDate);
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

2021-02-19T00:45:09.798Z
Run Code Online (Sandbox Code Playgroud)

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


* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用ThreeTen-Backport,它将大部分java.time功能向后移植到 Java 6 和 7。如果您正在为 Android 项目和您的 Android API 工作级别仍然不符合 Java-8,请检查通过 desugaringHow to use ThreeTenABP in Android Project可用的 Java 8+ APIs

  • 由于没有时区,我会在这里使用“Instant”或“OffsetDateTime”而不是“ZonedDateTime”。 (3认同)
  • @VGR UTC/Zulu 实际上“不是”时区。它是定义所有时区的基线。这就是为什么 *java.time* 提供与 `ZonedDateTime` 分开的 `Instant` 和 `OffsetDateTime` 类,以及为什么常量 `UTC` 定义在 `ZoneOffset` 类而不是 `ZoneId` 类上。偏移量只是小时数、分钟数、秒数,无论是正数还是负数。时区的意义要大得多。时区是特定地区的人们使用的偏移量的过去、现在和未来变化的历史。因此,对于这个答案,“ZonedDateTime”是不合适的。 (2认同)
  • 公平地说,还有“DateTimeFormatter.ISO_INSTANT”,它仅支持“Z”和Z,总是期待即时。因此,根据 OP 实际期望的输入类型,可以选择“Instant”(在“ZonedDateTime”和“OffsetDateTime”旁边),我认为我们无法真正从单个可用输入中看出。但是:Z_通常_表示偏移量,而不是ZoneId,尽管它也是一个很好的ZoneId。 (2认同)

Pet*_*ček 5

您输入的索引 23 是Z,时间偏移指示器。事实上,如果我们查看格式化模式文档,我们会看到“Z”作为偏移模式:

Offset Z: [...]一个、两个或三个字母输出小时和分钟,不带冒号,例如“+0130”。当偏移量为零时,输出将为“+0000”。

,并使用“X”作为偏移模式,同时使用“Z”表示零:

偏移量 X: [...]当要输出的偏移量为零时,模式字母“X”(大写)将输出“Z”。因此,这有效:

DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSX")
Run Code Online (Sandbox Code Playgroud)

也就是说,如果您的输入采用众所周知的 ISO 8601 标准格式,您可能需要使用预定义的格式化程序之一,例如ISO_OFFSET_DATE_TIME(或其他格式,具体取决于您输入的 ZoneId/offset 使用情况)。