Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
556 views
in Technique[技术] by (71.8m points)

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 (e.g. using DateTimeFormatter.ofPattern(pattern); (which I will only use for parsing, not formatting), it will interpret all two-letter years as 20xx, e.g. 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).

In my application, I'm trying to parse dates from OCR'd documents, which could e.g. 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. But for various reasons I'm still looking to switch the whole date parsing logic to the new 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. Is this simply not possible or have I missed some possibility of specifying the behavior for parsing two-letter years?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can create a custom formatter, for example for the d/M/yy pattern:

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...