This is because DateTimeFormatter.BASIC_ISO_DATE contains an optional offset identifier. Apparently your formatter parses -17 as an offset, and then objects, because there is a colon in which the format requires a hyphen.
When you use m instead, it cannot be parsed as an offset and therefore matches the literal m in the format, and everything works.
I tried using the capital letter Z Z may also be an identifier for the offset.
new DateTimeFormatterBuilder() .append(DateTimeFormatter.BASIC_ISO_DATE) .appendLiteral('Z') .append(DateTimeFormatter.ISO_LOCAL_TIME) .toFormatter() .parse("20180302Z17:45:21");
Now I got java.time.format.DateTimeParseException: Text '20180302Z17:45:21' could not be parsed at index 9 . Index 9 we immediately after Z , so it seems that the formatter is analyzing the offset, and then trying to find the literal Z , where 17 is located.
EDIT: And the solution? Instead of using BASIC_ISO_DATE add a template:
.appendPattern("uuuuMMdd")
Parsing now works on Java 9.0.4.
EDIT: Next, to illustrate the possibility of bias:
System.out.println( LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE) ); System.out.println( OffsetDateTime.now().format(DateTimeFormatter.BASIC_ISO_DATE) );
Printed
20180305 20180305+0100
So, in the first case, when the offset is not available, it simply does not work. In the second case, when it is available, it is also printed (without a colon).
An open question: why does it work in Java 8? Is this really a mistake?
Quote:
- If the offset is not available for formatting or parsing, the format will be completed.
- Displacement identifier without colons. If the offset has seconds, they will be processed, even if this does not apply to the ISO-8601 standard. Parsing the offset is soft, which allows you to use minutes and seconds - optional. The analysis is case insensitive.
From the documentation BASIC_ISO_DATE
Ole vv
source share