DateTimeFormatterBuilder appendOptional 多个 ISO 标准导致 DateTimeParseException

DateTimeFormatterBuilder appendOptional multiple ISO standards results in DateTimeParseException

public class Main {
  public static void main(String[] args) {  
        DateTimeFormatterBuilder dtf = new DateTimeFormatterBuilder()
                .appendOptional(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
                .appendOptional(DateTimeFormatter.ISO_OFFSET_DATE_TIME)
                .appendOptional(DateTimeFormatter.ISO_LOCAL_DATE);
        
        LocalDateTime x = LocalDateTime.parse("2021-10-11T07:00:53.004Z", dtf.toFormatter());
        System.out.println("After formatting: " + x);  
  }  
}  

所以我很好奇为什么这不起作用,他似乎自动假定第一个不是可选的?如果我交换 offset_date_time 和 local_date_time 它解析这个字符串而不是 local_date_time 字符串

Exception in thread "main" java.time.format.DateTimeParseException: Text '2021-10-11T07:00:53.004Z' could not be parsed, unparsed text found at index 23
    at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2053)
    at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1952)
    at java.base/java.time.LocalDateTime.parse(LocalDateTime.java:493)
    at Main.main(Main.java:12)

我在 Java 14 上,如果有任何不同,如果需要,我很乐意提供更多信息

最后我也改变了方法,允许所有 3 个 ISO 标准:

 public class Main {
      public static void main(String[] args) {  
    DateTimeFormatterBuilder dtf = new DateTimeFormatterBuilder()
            .append(DateTimeFormatter.ISO_LOCAL_DATE)
            .appendOptional(DateTimeFormatter.ofPattern("'T'"))
            .appendOptional(DateTimeFormatter.ISO_LOCAL_TIME)
            .appendOptional(DateTimeFormatter.ofPattern("XXX"));
            
            LocalDateTime x = LocalDateTime.parse("2021-10-11T07:00:53.004Z", dtf.toFormatter());
            System.out.println("After formatting: " + x);  
      }  
    }  

嗯,那是因为第一个可选部分可以完全消费,所以DateTimeFormatter消费了ISO_LOCAL_DATE_TIME表示的文本。

然后,对剩余文本Z尝试剩余的两个可选模式,但无法匹配。

最后,没有剩余模式可供解析,因此解析器注意到文本 Z 未被解析,因此抛出异常。