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.