Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DateTimeFormatter - Strict vs Lenient unexpected behaviour

I have some text that is only being parsed by a DateTimeFormatter when the parse style is Strict - and not when it's Lenient.

This seems like the opposite behaviour to what I'd expect?

Example:

String pattern = "ddMMyyHH:mm:ss";
String text = "02011104:21:32";

System.out.println(MessageFormat.format("Strict - {0}", new DateTimeFormatterBuilder().parseStrict().appendPattern(pattern).toFormatter().parse(text)));
System.out.println(MessageFormat.format("Lenient - {0}", new DateTimeFormatterBuilder().parseLenient().appendPattern(pattern).toFormatter().parse(text)));

Output:

Strict - {},ISO resolved to 2011-01-02T04:21:32
Exception in thread "main" java.time.format.DateTimeParseException: Text '02011104:21:32' could not be parsed at index 8
like image 265
Jakg Avatar asked Jul 15 '19 13:07

Jakg


1 Answers

Having posted this as a bug - https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8228353

I got the following reply:

According to DateTimeFormatterBuilder's spec, appendPattern("yy") translates to appendValueReduced(ChronoField.YEAR_OF_ERA, 2, 2000), where "2" applies both for with and maxWidth. In the method description, it reads:

For strict parsing, the number of characters allowed by width to maxWidth are parsed. For lenient parsing, the number of characters must be at least 1 and less than 10.

Thus in this case, only "11" is read for "yy" in strict mode, then produces the year "2011" with the base value 2000. But in lenient mode, "yy" tries to read greedily just before the ":" and produces the year "1104", then parser throws the exception trying to parse ":" with "HH" pattern.

like image 64
Jakg Avatar answered Nov 09 '22 15:11

Jakg