【问题标题】:DateTimeFormatterBuilder appendOptional multiple ISO standards results in DateTimeParseExceptionDateTimeFormatterBuilder appendOptional 多个 ISO 标准导致 DateTimeParseException
【发布时间】:2021-11-30 06:00:16
【问题描述】:
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);  
      }  
    }  

【问题讨论】:

  • 您的问题在于 Z 字符,您可以将 Z 放在 'Z' 之间,并为您的格式化程序示例使用一个简单的声明:DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm: ss.SSS'Z'");
  • @OussamaZAGHDOUD Z 是距 UTC 的偏移量(零),需要将其解析为偏移量。偏移量也可能类似于+02:00+00:00,因此硬编码文字Z 并不总是有效。
  • 是的,我的评论只适用于零偏移量,所以这不是一个很好的选择,感谢您的反馈:)。

标签: java java-14 datetimeformatter


【解决方案1】:

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

然后,剩余的两个可选模式将针对剩余的文本(Z)进行尝试,但它们无法匹配。

最后,没有模式可以解析了,所以解析器注意到文本Z没有被解析,因此抛出异常。

【讨论】:

  • 剩下的两种模式是针对文本 Z 还是全文尝试?
  • 不,已经被消费的文本将不再被解析。所以2021-10-11T07:00:53.004ISO_LOCAL_DATE_TIME 可选模式所消耗。
  • 然后我明白我哪里出错了,我不知道它允许部分消费,我想我可以将它匹配到不同的模式。我只需要通过附加每个模式的差异来使其更容易。谢谢!
猜你喜欢
  • 1970-01-01
  • 2018-06-08
  • 1970-01-01
  • 1970-01-01
  • 2012-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多