2015-09-10 32 views
6

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

在我的应用程序中,我试图解析OCR文件的日期,这可能来自例如90年代,所以将旧的SimpleDateFormat行为解释为在当前日期之前80年和之后20年之内的日期非常适合我,但由于各种原因,我仍然希望将整个日期解析逻辑切换到新的Java 8 DateTimeFormatters。

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

+0

[解析字符串的可能的复制本地日期不使用所需的世纪](http://stackoverflow.com/questions/29490893/parsing-string-to-local-date-doesnt-use-desired-century) –

回答

9

可以创建自定义格式,例如用于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年5月13日
13/5/34 = 2034年5月13日
13/5/33 = 2033年5月13日

+0

有点麻烦(因为我会有基本上解析我现有的模式列表,检查它是否包含“yy”,然后像你描述的那样构建格式化程序),但它确实可行,谢谢,我不知道我可以将模式的一部分与其他选项像那样! – David

+2

噢,并为人们提示同样的问题:appendValueReduced(ChronoField.YEAR_OF_ERA,2,4,LocalDate.now()。minusYears(80))让您能够解析两个字符和四个字符的年份! – David

相关问题