如何使用Java 8 DateTimeFormatter更改解析两个字母年份的基准日期?

如果我使用像d/M/yy这样的模式来创建Java 8 DateTimeFormatter(例如使用DateTimeFormatter.ofPattern(pattern); (我将只用于解析,而不是格式化),它会将所有两个字母的年份解释为20xx例如解析像13/5/99这样的字符串被解释为2099-05-13 ,在我的情况下是错误的(它本来是在1999年)。

在我的应用程序中,我正在尝试从OCR文档中解析日期,这可能仍然是从90年代开始的,所以使用旧的SimpleDateFormat行为将日期解释为在当前日期之前和之后的20年之内我很好。 但由于各种原因,我仍然希望将整个日期解析逻辑切换到新的Java 8 DateTimeFormatters。

浏览Java源代码,我发现这都是相对于常量ReducedPrinterParser.BASE_DATE解释的,但我认为无法更改从模式构建自己的格式化程序时使用的值。 这是不可能的,还是我错过了指定解析两个字母年份的行为的可能性?

您可以创建自定义格式化程序,例如d/M/yy模式:

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

用法示例:

 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)); } 

打印:

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