Home > Back-end >  DateTimeFormatterBuilder appendOptional multiple ISO standards results in DateTimeParseException
DateTimeFormatterBuilder appendOptional multiple ISO standards results in DateTimeParseException

Time:10-11

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);  
  }  
}  

so i was curious why this does not work, it seems like he automatically assumes the first one to not be optional? if i swap offset_date_time and local_date_time it parses this string but not the local_date_time string

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)

im on Java 14 if that makes any difference, i would be happy to provide additional information if necassery

CodePudding user response:

Well, that is because the first optional part can be fully consumed, so the DateTimeFormatter consumes the text denoted by the ISO_LOCAL_DATE_TIME.

Then, the two remaining optional patterns are tried against the remaining text, which is Z, but they cannot be matched.

At last, there is no pattern left to parse, so the parser notes that the text Z is left unparsed, hence an exception is thrown.

CodePudding user response:

Optional patterns work like OR (i.e. ||) i.e. the next one is tried only when the previous one gets evaluated successfully and returns false until all the options are exhausted e.g.

x || y || z

Here, first x is evaluated and if it gets evaluated successfully and returns false, y is evaluated and so one. The evaluation stops at the step where the result becomes true.

In your case, first DateTimeFormatter.ISO_LOCAL_DATE_TIME is tried but it will fail because 2021-10-11T07:00:53.004Z can not be parsed into a LocalDateTime and therefore the corresponding exception is thrown.

If you swap it with DateTimeFormatter.ISO_OFFSET_DATE_TIME, first DateTimeFormatter.ISO_OFFSET_DATE_TIME will be tried which will pass.

  • Related