While JodaStephen has nicely explained the reason for the exception and given one good solution (use uu
rather than yy
), I am offering a couple of other possible solutions:
- The obvious one that you probably don’t want: leave the resolver style at
SMART
(the default). In other words either leave out .withResolverStyle(ResolverStyle.STRICT)
completely or change it to .withResolverStyle(ResolverStyle.SMART)
.
- Provide a default era.
For the second option here is a code example:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendPattern("yyMMdd")
.parseDefaulting(ChronoField.ERA, 1)
.toFormatter()
.withResolverStyle(ResolverStyle.STRICT);
String expiryDate = "160501";
LocalDate result = LocalDate.parse(expiryDate, formatter);
System.out.println(result);
Output is:
2016-05-01
Where the last solution may make a difference compared to using uu
in the format pattern:
- It allows us to use a format pattern that is given to us where we cannot control whether pattern letter
u
or y
is used.
- With pattern letter
y
it will fail with an exception if the string contains a negative year. Depending on your situation and requirements this may be desirable or unacceptable.
Edit: The second argument to parseDefaulting()
may also be written IsoEra.CE.getValue()
rather than just 1
to make it clear that we are specifying the current era (CE; also often called Anno Domini or AD).
java.time
-design is not clever enough to recognize that - in absence of era field - the year-of-era (symbol y) should be handled like proleptic gregorian year (symbol u). In addition, the original ISO-8601-paper does not say anything about eras. Therefore a plain year-month-day-combination should really be handled like what ISO says, ignoring the era and using the proleptic gregorian calendar. – Coordination