Mr Shorly
Mr Shorly

Reputation: 149

DateTimeParseException for DateTimeFormatter with pattern "yyyy[-MM[-d[ HH[:mm[:ss[.SSS]]]]]"

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

Answers (1)

DaveyDaveDave
DaveyDaveDave

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

Related Questions