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

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

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

在我的应用程序中,我试图从 OCR 文档中解析日期,例如仍然来自 90 年代,因此将日期解释为当前日期之前 80 年和当前日期之后 20 年内的旧 SimpleDateFormat 行为非常适合我。但是出于各种原因,我仍然希望将整个日期解析逻辑切换到新的 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