It appears to me that the spring annotation @DateTimeFormat bound to an attribute of type LocalDate
will cause Spring to choose a JodaTime-Formatter, not the standard formatter, otherwise Spring would not be able to successfully parse any input string to an object of type LocalDate
. This statement is done on the analysis of Spring source code (see implementation of method getParser(DateTimeFormat annotation, Class<?> fieldType)
).
If so then the question remains why your work-around and solution "dd.MM.yy" is able to parse two-digit-years as well as normal four-digit-years. The answer can be found in Joda sources and documentation.
Source extract of org.joda.time.format.DateTimeFormat (pattern analysis of JodaTime done in private method parsePatternTo(DateTimeFormatterBuilder builder, String pattern)
):
case 'y': // year (number)
case 'Y': // year of era (number)
if (tokenLen == 2) {
boolean lenientParse = true;
// Peek ahead to next token.
if (i + 1 < length) {
indexRef[0]++;
if (isNumericToken(parseToken(pattern, indexRef))) {
// If next token is a number, cannot support
// lenient parse, because it will consume digits that it should not.
lenientParse = false;
}
indexRef[0]--;
}
// Use pivots which are compatible with SimpleDateFormat.
switch (c) {
case 'x':
builder.appendTwoDigitWeekyear(new DateTime().getWeekyear() - 30, lenientParse);
break;
case 'y':
case 'Y':
default:
builder.appendTwoDigitYear(new DateTime().getYear() - 30, lenientParse);
break;
}
So we recognize that JodaTime translates the pattern expression "yy" to a call to builder-method appendTwoDigitYear()
with the argument lenientParse set to true
. Interesting also that the choosen pivot year deviates from usual Joda setting (+/-50 years), namely (-80/+20 years).
In the Javadoc of mentioned builder-method it is said:
"lenientParse - when true, if digit count is not two, it is treated as an absolute year"
That sufficiently explains why "dd.mm.yy" can as well parse two-digit-years as four-digit-years.