11

如果我使用像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,但是我看不到在从模式构建我自己的格式化程序时更改使用的值。这根本不可能,还是我错过了一些指定解析两个字母年份的行为的可能性?

4

1 回答 1

14

您可以创建自定义格式化程序,例如用于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

于 2015-09-10T15:20:15.487 回答