I have a simple problem : I want to parse Java strings in format "yyyyMMdd" strictly, so that "19800229" is a valid date, but "19820229" is not. Assume these are AD dates from the normal Gregorian calendar.
I am trying to use the new java.time package from JDK 8 to solve this problem, but it is proving more complicated than hoped. My current code is:
private static final DateTimeFormatter FORMAT = DateTimeFormatter
.ofPattern("yyyyMMdd").withChronology(IsoChronology.INSTANCE)
.withResolverStyle(STRICT);
public static LocalDate parse(String yyyyMMdd) {
return LocalDate.parse(yyyyMMdd, FORMAT);
}
However, parsing a valid date such as "19800228" produces what to me is an incomprehensible error:
java.time.format.DateTimeParseException: Text '19820228' could not be parsed: Unable to obtain LocalDate from TemporalAccessor: {MonthOfYear=2, DayOfMonth=28, YearOfEra=1982},ISO of type java.time.format.Parsed
How do I use java.time.format.DateTimeFormatter to solve my simple use case?
Java 8 uses uuuu for year, not yyyy. In Java 8, yyyy means "year of era" (BC or AD) and the error message complains that MonthOfYear, DayOfMonth and YearOfEra is not enough information to construct the date because era is not known.
To fix that, use uuuu in your format string, e.g. DateTimeFormatter.ofPattern("uuuuMMdd")
Or, if you want to keep using yyyy, you can set the default era, e.g.
private static final DateTimeFormatter FORMAT = new DateTimeFormatterBuilder()
.appendPattern("yyyyMMdd")
.parseDefaulting(ChronoField.ERA, 1 /* era is AD */)
.toFormatter()
.withChronology(IsoChronology.INSTANCE)
.withResolverStyle(ResolverStyle.STRICT);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With