Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java8 appendPattern vs pattern defined by appendValue methods produces different result

I have the pattern "ddMMyy" in my code I have specified it 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 produces "0099" for year:

0099-01-10

If I change that to using the appendPattern like that:

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

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

2099-01-10

The code seems equivalent for me why isn't it producing the same result? Why is the century missing in the first case?

like image 837
Ivelina Georgieva Avatar asked Jul 15 '16 14:07

Ivelina Georgieva


1 Answers

Because appendValue takes the year as it is being passed without further manipulation - in your case 99.

If you want to start from a "base year", say 2000, and add the value to that base year (to get 2099) you can use appendValueReduced instead:

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 pattern, you get that behaviour by default as detailed in the javadoc:

Year: The count of letters determines the minimum field width below which padding is used. If the count of letters is two, then a reduced two digit form is used. For printing, this outputs the rightmost two digits. For parsing, this will parse using the base value of 2000, resulting in a year within the range 2000 to 2099 inclusive. [...]

like image 174
assylias Avatar answered Nov 01 '22 17:11

assylias