Reputation: 149
I would like to create a DateTimeFormatter that accepts different types of formats like: "2018", "2018-01-02" or "2018-01-02 10:15". I tried to build it like this:
DateTimeFormatter f1 = new DateTimeFormatterBuilder()
.appendPattern("yyyy[-MM[-d[ HH[:mm[:ss[.SSS]]]]]")
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
.parseDefaulting(ChronoField.MONTH_OF_YEAR, 1)
.toFormatter();
LocalDateTime.parse("2018-01", f1); // no problem
LocalDateTime.parse("2018", f1); // exception
The second line gives the following exception:
java.time.format.DateTimeParseException: Text '2018' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {Year=2018},ISO of type java.time.format.Parsed
at java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1920)
This formatter will work for all my cases except for the simple "2018". Can anyone tell me why?
Strangely the formatter of the next codeblock will accept the "2018":
DateTimeFormatter f2 = new DateTimeFormatterBuilder()
.appendPattern("yyyy[-MM[-d]]")
.parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
.parseDefaulting(ChronoField.MONTH_OF_YEAR, 1)
.toFormatter();
LocalDate.parse("2018", f2); // no problem
Upvotes: 4
Views: 380
Reputation: 10612
I think you just have mis-matched square brackets.
I tried your original example:
DateTimeFormatter f1 = new DateTimeFormatterBuilder()
.appendPattern("yyyy[-MM[-d[ HH[:mm[:ss[.SSS]]]]]")
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
.parseDefaulting(ChronoField.MONTH_OF_YEAR, 1)
.toFormatter();
and get the same exception as you, but when I add one more ]
, it works as expected, so this works for me:
DateTimeFormatter f1 = new DateTimeFormatterBuilder()
.appendPattern("yyyy[-MM[-d[ HH[:mm[:ss[.SSS]]]]]]")
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
.parseDefaulting(ChronoField.MONTH_OF_YEAR, 1)
.toFormatter();
To help compare:
.appendPattern("yyyy[-MM[-d[ HH[:mm[:ss[.SSS]]]]]") // throws exception
.appendPattern("yyyy[-MM[-d[ HH[:mm[:ss[.SSS]]]]]]") // works fine
Upvotes: 4