Java8 appendPattern vs. template defined by appendValue methods gives excellent result

I have a "ddMMyy" template in my code that I specified using the appendValue methods:

DateTimeFormatter dateTimeFormatter = new DateTimeFormatterBuilder() .appendValue(ChronoField.DAY_OF_MONTH, 2) .appendValue(ChronoField.MONTH_OF_YEAR, 2) .appendValue(ChronoField.YEAR_OF_ERA, 2) .toFormatter(); System.out.println(LocalDate.parse("100199", dateTimeFormatter)); 

However, this gives "0099" for the year:

0099-01-10

If I changed this to use appendPattern as follows:

 DateTimeFormatter dateTimeFormatter = new DateTimeFormatterBuilder() .appendPattern("ddMMyy") .toFormatter(); System.out.println(LocalDate.parse("100199", dateTimeFormatter)); 

I have the correct result for the year "2099" with a century in it.

2099-01-10

The code seems equivalent to me, why doesn't it produce the same result? Why is the first case missing a century?

+7
java datetime java-8 java-time
source share
1 answer

Because appendValue takes a year because it is passed without further manipulation - in your case 99.

If you want to start with a “base year,” say 2000, and add a value to that base year (to get 2099), you can use appendValueReduced :

 DateTimeFormatter dateTimeFormatter = new DateTimeFormatterBuilder() .appendValue(ChronoField.DAY_OF_MONTH, 2) .appendValue(ChronoField.MONTH_OF_YEAR, 2) .appendValueReduced(ChronoField.YEAR_OF_ERA, 2, 2, LocalDate.of(2000, 1, 1)) .toFormatter(); 

When you use the yy template, you get this default behavior, as described in javadoc :

Year The number of letters determines the minimum width of the box below which the pad is used. If the number of letters is two, the abbreviated two-digit form is used. For printing, this gives the rightmost two digits. For parsing, this will be analyzed using a base value of 2000, resulting in a year-long range from 2000 to 2099 inclusive. [...]

+6
source share

All Articles