Java 为什么我的日期时间解析尝试失败?

Java 为什么我的日期时间解析尝试失败?,java,parsing,datetime,java-8,java-time,Java,Parsing,Datetime,Java 8,Java Time,我正在用两种稍微不同的格式解析同一个日期,我遇到了一个我不理解的错误 成功解析标准ISO格式的字符串: String s = "2018-04-17T22:57:29"; LocalDateTime date = LocalDateTime.parse(s, DateTimeFormatter.ISO_DATE_TIME); // OK 但是,当我将后缀a“Z”作为后缀并使用ISO_INSTANT时,因此: s = "2018-04-17T22:57:29Z";

我正在用两种稍微不同的格式解析同一个日期,我遇到了一个我不理解的错误

成功解析标准ISO格式的字符串:

    String s = "2018-04-17T22:57:29";
    LocalDateTime date = LocalDateTime.parse(s, DateTimeFormatter.ISO_DATE_TIME);  // OK
但是,当我将后缀a
“Z”
作为后缀并使用
ISO_INSTANT
时,因此:

    s = "2018-04-17T22:57:29Z";
    date = LocalDateTime.parse(s, DateTimeFormatter.ISO_INSTANT); // Fails
我得到以下例外情况:

Exception in thread "main" java.time.format.DateTimeParseException: Text '2018-04-17T22:57:29Z' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {MicroOfSecond=0, NanoOfSecond=0, MilliOfSecond=0, InstantSeconds=1524005849},ISO of type java.time.format.Parsed
at java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1920)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1855)
at java.time.LocalDateTime.parse(LocalDateTime.java:492)
at iplus.fwk.manifest.Test.main(Test.java:37)
Caused by: java.time.DateTimeException: Unable to obtain LocalDateTime from TemporalAccessor: {MicroOfSecond=0, NanoOfSecond=0, MilliOfSecond=0, InstantSeconds=1524005849},ISO of type java.time.format.Parsed
at java.time.LocalDateTime.from(LocalDateTime.java:461)
at java.time.format.Parsed.query(Parsed.java:226)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
... 2 more
Caused by: java.time.DateTimeException: Unable to obtain LocalDate from TemporalAccessor: {MicroOfSecond=0, NanoOfSecond=0, MilliOfSecond=0, InstantSeconds=1524005849},ISO of type java.time.format.Parsed
at java.time.LocalDate.from(LocalDate.java:368)
at java.time.LocalDateTime.from(LocalDateTime.java:456)
... 4 more
我的解读
建议第二次解析应该成功。我做错了什么?

我认为正确的思考方式是:从概念上讲,瞬间不是日期和时间。只是,一瞬间。它没有时区或偏移,因此不能有日期和时间。由于
LocalDateTime
需要一天中的日期和时间,因此作为瞬间解析并不能提供所需的内容

是的,我知道:
Instant
的实现使用自纪元以来的时间,目前为止,纪元最常见的定义使用UTC。我还知道您正在解析的字符串包含日期和时间,并且
DateTimeFormatter.ISO_INSTANT
INSTANT.toString
都会生成类似的字符串。不过,这只是一个界面,并没有告诉您瞬间的概念是什么

我对ISO_INSTANT定义的解读表明 解析应该成功

我知道这个定义可以这样理解。但我认为这一点值得注意:

…瞬间由ChronoField.instant\u秒和 时间场,纳米秒

虽然nano of second与其他日期时间类型(如
LocalDateTime
)共享,但提到的两个字段不足以获取
LocalDateTime
的数据。所以这就是它为你打破的地方。要获得
LocalDateTime
,我们需要假设时区或偏移量。尽管这句话还在继续:

…使用UTC偏移量

-这只意味着UTC偏移量用于计算瞬间秒数和纳秒数,而不是用于进一步处理

我们还可以尝试更仔细地研究您的错误消息:

线程“main”java.time.format.DateTimeParseException中的异常: 无法分析文本“2018-04-17T22:57:29Z”:无法获取 来自TemporalAccessor的LocalDateTime:{MicroOfSecond=0,nanofSecond=0, 毫秒=0,瞬间秒=1524005849},ISO类型 java.time.format.Parsed

这也意味着我们从解析中得到的只是瞬间秒数(即从纪元开始的秒数)和秒数分数(以及ISO年表)。这还不足以获得
LocalDateTime

你不是第一个(也不是最后一个)感到惊讶的人。不过,你观察到的行为是故意的

修复

ISO_INSTANT
的定义还提到:

ISO偏移量日期时间的

所以这是可行的:

    String s = "2018-04-17T22:57:29Z";
    LocalDateTime date = LocalDateTime.parse(s, DateTimeFormatter.ISO_OFFSET_DATE_TIME);

结果是
2018-04-17T22:57:29
(如预期)。

感谢您给出清晰详细的答案。高分!