I have a requirement for parsing ISO8601 formatted strings in Java with various levels of accuracy. Some examples of the string I need to parse are:
Well that took me longer than I had expected. The only valid parser is:
DateTimeFormatter dtf = new DateTimeFormatterBuilder()
.appendValue(ChronoField.YEAR, 4)
.appendPattern("[['-']MM[['-']dd[['T']HH[[':']mm[[':']ss['.'SSS]]]]]]")
.parseDefaulting(ChronoField.MONTH_OF_YEAR, 1)
.parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
.parseDefaulting(ChronoField.NANO_OF_SECOND, 0)
.toFormatter();
String[] s = {
"2018",
"2018-10",
"2018-10-15",
"2018-10-15T12:00",
"2018-10-15T12:00:30",
"2018-10-15T12:00:30.123",
"20181015",
"201810151200",
"20181015120030",
"20181015120030.123",
"20181015T12:00:30.123"
};
for (String line : s) {
System.out.println(LocalDateTime.parse(line, dtf));
}
The problem is that yyyy
creates a ValueParser(minWidth=4, maxWidth=19, SignStyle.PAD_EXEEDS)
which parses the date 20181015
as year=20181015
as an example. So we have to restrict the digit width of year
to 4.
The documentation states:
Year: The count of letters determines the minimum field width below which padding is used.
But does not specify a maximum width.