If I use a pattern like d/M/yy
for creating a Java 8 DateTimeFormatter (e.g. using DateTimeFormatter.ofPattern(pattern);
(which I will only use for parsing, not formatting), it will interpret all two-letter years as 20xx, e.g. parsing a string like 13/5/99
to be interpreted as 2099-05-13
, which in my case is wrong (it was meant to be in the year 1999).
In my application, I'm trying to parse dates from OCR'd documents, which could e.g. still be from the 90ies, so having the old SimpleDateFormat behavior of interpreting the date to be within 80 years before and 20 years after the current date fits me quite well. But for various reasons I'm still looking to switch the whole date parsing logic to the new Java 8 DateTimeFormatters.
Looking through the Java source code, I see that this is all interpreted relative to the constant ReducedPrinterParser.BASE_DATE
, but I see no way to change the value used when building my own formatter from a pattern. Is this simply not possible or have I missed some possibility of specifying the behavior for parsing two-letter years?
You can create a custom formatter, for example for the d/M/yy
pattern:
new DateTimeFormatterBuilder()
.appendPattern("d/M/")
.appendValueReduced(ChronoField.YEAR_OF_ERA, 2, 2, LocalDate.now().minusYears(80))
Example usage:
public static void main(String[] args) throws Exception {
DateTimeFormatter fmt = new DateTimeFormatterBuilder()
.appendPattern("d/M/")
.appendValueReduced(ChronoField.YEAR_OF_ERA, 2, 2, LocalDate.now().minusYears(80))
.toFormatter();
parse("13/5/99", fmt);
parse("13/5/36", fmt);
parse("13/5/35", fmt);
parse("13/5/34", fmt);
parse("13/5/33", fmt);
}
private static void parse(String date, DateTimeFormatter fmt) {
System.out.println(date + " = " + LocalDate.parse(date, fmt));
}
which prints:
13/5/99 = 1999-05-13
13/5/36 = 1936-05-13
13/5/35 = 1935-05-13
13/5/34 = 2034-05-13
13/5/33 = 2033-05-13