由appendValue方法定义的Java8 appendPattern vs pattern产生不同的结果

Ive*_*eva 7 java datetime java-8 java-time

我的代码中有"ddMMyy"模式,我使用appendValue方法指定了它:

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));
Run Code Online (Sandbox Code Playgroud)

但是这会产生"0099"年份:

0099-01-10

如果我将其更改为使用appendPattern:

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

我有正确的结果,一年"2099"与世纪.

2099年1月10日

代码对我来说似乎相同,为什么它不能产生相同的结果?为什么在第一种情况下缺少这个世纪?

ass*_*ias 6

因为appendValue在没有进一步操纵的情况下通过了这一年 - 在你的情况下99.

如果您想从"基准年"开始,比如2000,并将该值添加到该基准年(到2099年),您可以使用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();
Run Code Online (Sandbox Code Playgroud)

当您使用该yy模式时,默认情况下会获得该行为,详见javadoc:

年份:字母数决定了使用填充的最小字段宽度.如果字母数是2,则使用减少的两位数形式.对于打印,这将输出最右边的两位数字.对于解析,这将使用2000的基值进行解析,从而产生2000到2099(包括2000和2099)范围内的一年.[...]