简体   繁体   中英

Parsing 2-digit years: Setting the pivot date with an unknown date pattern

The user will input dates in different patterns to my application. For 2-digit years, he must also determine the pivot date.


Example:
pattern = yy-MM-dd
pivot date = 70 (I add the current millennium and the last century for more dynamics programmatically => 1970 )

69-04-22 becomes 2069-04-22
70-04-22 becomes 1970-04-22


Like described in this answer it's easy to build a DateTimeFormatter when the date pattern (here ddMMyy ) is known.
But since the user inputs the pattern, I'm not sure how to build the DateTimeFormatterBuilder properly. I can't hard code it.

Do I have to parse the pattern by myself and call appendPattern() and appendValueReduced() in the right order? Or is there a built-in solution?

Here the Java-8-solution (it rather looks like a hack):

String pattern = "MM/dd/yy 'US'"; // user-input
String text = "10/04/69 US"; // user-input
Locale locale = Locale.US; // user-input, too?

int yy = pattern.indexOf("yy");
DateTimeFormatter dtf;

if (
    (yy != -1) // explanation: condition ensures exactly two letters y
    && ((yy + 2 >= pattern.length()) || pattern.charAt(yy + 2) != 'y')
) {
    DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder();
    String part1 = pattern.substring(0, yy);
    if (!part1.isEmpty()) {
        builder.appendPattern(part1);
    }
    builder.appendValueReduced(ChronoField.YEAR, 2, 2, 1970);
    String part2 = pattern.substring(yy + 2);
    if (!part2.isEmpty()) {
        builder.appendPattern(part2);
    }
    dtf = builder.toFormatter(locale);
} else {
    dtf = DateTimeFormatter.ofPattern(pattern, locale);
}

LocalDate ld = LocalDate.parse(text, dtf);
System.out.println("user-date: " + ld); // 2069-10-04

There is only one tiny caveat: If any user gets the crazy idea to define two times separately "yy" in the pattern then the proposed solution will fail. The correct solution would then require some kind of iterating over the pattern chars but I think that is overkill, so I leave it out here.

Just for comparison, using my external library Time4J enables following short solution because its parse engine also has the concept of setting any suitable format attributes:

LocalDate ld = 
  ChronoFormatter.ofDatePattern(pattern, PatternType.CLDR, locale)
  .with(Attributes.PIVOT_YEAR, 2070).parse(text).toTemporalAccessor();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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