How to change the base date for parsing two-letter years using Java 8 DateTimeFormatter?

If I use a template like d/M/yy to create a Java 8 DateTimeFormatter (e.g. using DateTimeFormatter.ofPattern(pattern); (which I will use only for parsing, not formatting), it will interpret all two-letter years as 20xx. for example, parsing a string like 13/5/99 should be interpreted as 2099-05-13 , which in my case is incorrect (it should have been in 1999).

In my application, I am trying to analyze dates from OCR'd documents, which could, for example, still be from the 90s, so having the old SimpleDateFormat behavior to interpret the date 80 years before and 20 years after the current date suits me quite well. But for various reasons, I'm still trying to switch all the parsing logic to the new Java 8 DateTimeFormatters.

Looking through the Java source code, I see that all this is interpreted with respect to the ReducedPrinterParser.BASE_DATE constant, but I see no way to change the value used when creating my own formatting from the template. Is this just impossible or did I miss any opportunity to specify behavior for parsing two-letter years?

+9
source share
1 answer

You can create your own formatter, for example, for the d/M/yy template:

 new DateTimeFormatterBuilder() .appendPattern("d/M/") .appendValueReduced(ChronoField.YEAR_OF_ERA, 2, 2, LocalDate.now().minusYears(80)) 

Usage example:

 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

+11
source

All Articles