简体   繁体   English

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

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

If I use a pattern like d/M/yy for creating a Java 8 DateTimeFormatter (eg using DateTimeFormatter.ofPattern(pattern); (which I will only use for parsing, not formatting), it will interpret all two-letter years as 20xx, eg 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). 如果我使用像d/M/yy这样的模式来创建Java 8 DateTimeFormatter(例如使用DateTimeFormatter.ofPattern(pattern); (我将只用于解析,而不是格式化),它会将所有两个字母的年份解释为20xx例如解析像13/5/99这样的字符串被解释为2099-05-13 ,在我的情况下是错误的(它本来是在1999年)。

In my application, I'm trying to parse dates from OCR'd documents, which could eg 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. 在我的应用程序中,我试图解析OCR'd文档中的日期,例如仍然可以从90年代开始,所以使用旧的SimpleDateFormat行为将日期解释为在当前日期之前和之后的20年之内我很好。 But for various reasons I'm still looking to switch the whole date parsing logic to the new Java 8 DateTimeFormatters. 但由于各种原因,我仍然希望将整个日期解析逻辑切换到新的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. 通过Java源代码,我看到这都是相对于常量ReducedPrinterParser.BASE_DATE解释的,但我认为无法更改从模式构建自己的格式化程序时使用的值。 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: 您可以创建自定义格式化程序,例如d/M/yy模式:

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/99 = 1999-05-13
13/5/36 = 1936-05-13 13/5/36 = 1936-05-13
13/5/35 = 1935-05-13 13/5/35 = 1935-05-13
13/5/34 = 2034-05-13 13/5/34 = 2034-05-13
13/5/33 = 2033-05-13 13/5/33 = 2033-05-13

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM