Java DateTimeFormatter is not parsing as expected

Viewed 317

I tried DateTimeFormatter to parse input date to dd/MM/yyyy. I have used below code

java.time.format.DateTimeFormatter is failing to parse the date

  DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy").withResolverStyle(ResolverStyle.STRICT);
    
       
            try {
                LocalDate.parse(dateField, dateFormatter);
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        
        return true;
    }

Input: 30/04/2018

Error:Caused by: java.time.DateTimeException: Unable to obtain LocalDate from TemporalAccessor: {MonthOfYear=4, YearOfEra=2018, DayOfMonth=30},ISO of type java.time.format.Parsed

It is also failing for leap years.

2 Answers

The issue is using .withResolverStyle(ResolverStyle.STRICT) requires to use year pattern uuuu instead of yyyy (i.e. "year" instead of "year-of-era")

You basically have two options (here, where one is using the ResolverStyle you are showing in your code example):

  • use a ResolverStyle.STRICT explicitly ⇒ parses year u only
  • use a default ResolverStyleyear-of-era y or year u will be parsed

The following example shows the differences in code:

public static void main(String[] args) {
    String date = "30/04/2018";
    // first formatter with year-of-era but no resolver style
    DateTimeFormatter dtfY = DateTimeFormatter.ofPattern("dd/MM/yyyy");
    // second one with year and a strict resolver style
    DateTimeFormatter dtfU = DateTimeFormatter.ofPattern("dd/MM/uuuu")
                                                .withResolverStyle(ResolverStyle.STRICT);
    // parse
    LocalDate localDateU = LocalDate.parse(date, dtfU);
    LocalDate localDateY = LocalDate.parse(date, dtfY);
    // print results
    System.out.println(localDateU);
    System.out.println(localDateY);
}

The output is

2018-04-30
2018-04-30

so both DateTimeFormatters parse the very same String, but the one without a ResolverStyle explicitly attached will use ResolverStyle.SMART by default according to the JavaDocs of DateTimeFormatter.

Of course, a pattern with year (u) will be parsed by ResolverStyle.SMART, too, so

DateTimeFormatter.ofPattern("dd/MM/uuuu");

would be an option as well.

A good explanation of the difference between year-of-era and year can be found in this post.

Related