I am trying to port some code from joda time to java time.
JodaTime had the possibility to specify a fallback value for the year like this
parser.withDefaultYear((new DateTime(DateTimeZone.UTC)).getYear()).parseDateTime(text);
Regardless how the parser looks (if it includes a year or not), this will be parsed.
java.time has become much more stricter there. Even though there is the DateTimeFormatterBuilder.parseDefaulting()
method, which allows you to specify fallbacks, this only works if that specific field is not specified in the date your want to parse or is marked as optional.
If you do not have any control about the incoming date format, as it is user supplied, this makes it super hard when to call parseDefaulting
.
Is there any workaround, where I can specify something like either a generic fallback date, whose values get used by the formatter, if they are not specified or how I configure fallback values that are simply not used, when they are specified in the formatter?
Minimal, complete and verifiable example follows.
public static DateTimeFormatter ofPattern(String pattern) {
return new DateTimeFormatterBuilder()
.appendPattern(pattern)
.parseDefaulting(ChronoField.YEAR, 1970)
.toFormatter(Locale.ROOT);
}
public void testPatterns() {
// works
assertThat(LocalDate.from(ofPattern("MM/dd").parse("12/06")).toString(), is("1970-12-06"));
assertThat(LocalDate.from(ofPattern("uuuu/MM/dd").parse("2018/12/06")).toString(), is("2018-12-06"));
// fails with exception, as it uses year of era
assertThat(LocalDate.from(ofPattern("yyyy/MM/dd").parse("2018/12/06")).toString(), is("2018-12-06"));
}
Desired result: The test should parse the strings and pass (“be green”).
Observed result: The last line of the test throws an exception with the following message and stack trace.
Text '2018/12/06' could not be parsed: Conflict found: Year 1970 differs from Year 2018
Exception in thread "main" java.time.format.DateTimeParseException: Text '2018/12/06' could not be parsed: Conflict found: Year 1970 differs from Year 2018
at java.base/java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1959)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1820)
at com.ajax.mypackage.MyTest.testPatterns(MyTest.java:33)
Caused by: java.time.DateTimeException: Conflict found: Year 1970 differs from Year 2018
at java.base/java.time.chrono.AbstractChronology.addFieldValue(AbstractChronology.java:676)
at java.base/java.time.chrono.IsoChronology.resolveYearOfEra(IsoChronology.java:620)
at java.base/java.time.chrono.IsoChronology.resolveYearOfEra(IsoChronology.java:126)
at java.base/java.time.chrono.AbstractChronology.resolveDate(AbstractChronology.java:463)
at java.base/java.time.chrono.IsoChronology.resolveDate(IsoChronology.java:585)
at java.base/java.time.chrono.IsoChronology.resolveDate(IsoChronology.java:126)
at java.base/java.time.format.Parsed.resolveDateFields(Parsed.java:360)
at java.base/java.time.format.Parsed.resolveFields(Parsed.java:266)
at java.base/java.time.format.Parsed.resolve(Parsed.java:253)
at java.base/java.time.format.DateTimeParseContext.toResolved(DateTimeParseContext.java:331)
at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1994)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1816)
... 1 more