2

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.

Mario Codes
  • 689
  • 8
  • 15
Anoop M Nair
  • 1,057
  • 1
  • 13
  • 31
  • 3
    Make the pattern `"dd/MM/uuuu"`... Or leave the `ResolverStyle`, but if you want a `ResolverStyle.STRICT` you will have to use year (`u`) instead of year-of-era (`y`). – deHaar Sep 02 '20 at 13:39
  • 1
    @deHaar — or provide a default era using `DateTimeFormatterBuilder.parseDefaulting()`. – Ole V.V. Sep 02 '20 at 13:56
  • 1
    @OleV.V. that should be added as another answer... Or added to one of the existing ones, but I don't have time left. – deHaar Sep 02 '20 at 13:59
  • @deHaar I think I found a better fit for an original question. I have added it and written [a new answer here](https://stackoverflow.com/a/63708336/5772882). – Ole V.V. Sep 02 '20 at 15:06

2 Answers2

3

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

layonez
  • 1,746
  • 1
  • 16
  • 20
1

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.

deHaar
  • 17,687
  • 10
  • 38
  • 51