The user will input dates in different patterns to my application. For 2-digit years, he must also determine the pivot date.
Example:
patt
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();