Java DateTimeFormatterBuilder与指定的parseDefaulting冲突年份字段

Java DateTimeFormatterBuilder与指定的parseDefaulting冲突年份字段,java,datetime,java-8,java-time,Java,Datetime,Java 8,Java Time,我有以下格式化程序: DateTimeFormatter formatter = new DateTimeFormatterBuilder() .appendPattern("yyyyMM") .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0) .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0) .parseDefaulting(Chrono

我有以下格式化程序:

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
        .appendPattern("yyyyMM")
        .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
        .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
        .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
        .parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
        .parseDefaulting(ChronoField.MONTH_OF_YEAR, 1)
        .parseDefaulting(ChronoField.YEAR, ZonedDateTime.now().getYear())
        .toFormatter()
        .withZone(ZoneId.systemDefault());
我试图解析字符串“201505”

它抛出了一个异常:

原因:java.time.DateTimeException:发现冲突:2016年 与2015年不同

如果我注释掉年的默认值设置,它就可以工作

就我对文档的理解而言,只有在没有解析值的情况下,它才应该尝试替换默认值。似乎这对月份有效,因为我的月份与解析的默认月份不同。然而,它在一年内都不起作用


我用错了吗?有人能告诉我,是否有不同的方法来定义模式中可能不存在的字段的默认值吗?

问题是模式字母“y”指的是
ChronoField.YEAR\u OF ERA
,而不是
ChronoField.YEAR
。只需更改最后的
parseDefaulting
行:

.parseDefaulting(ChronoField.YEAR_OF_ERA, ZonedDateTime.now().getYear())

它应该可以工作。

为什么要将格式为“yyyyMM”的输入解析为
zoneDateTime
而不是
YearMonth
?我有一个解析不同格式的代码,格式化程序接收到的格式大约有40-50种。我想使用一个通用的格式化程序进行解析,它总是产生一个ZoneDateTime。这只是我的案例之一。哦,真的是40-50模式吗?你也有不同的地区吗?性能如何?由于内部异常抛出/捕获,它一定是坏的。你能报告一下你的速度经验吗?对不起,我不清楚。它们不会同时被解析。我只是有一些通用代码,可以解析对象,然后对其执行一些附加操作。对于Joda time,它可以很好地处理DateTime,但是对于新的java api,您需要有不同的对象。。这就是我现在不想要的,因为我想在不改变太多东西的情况下移植到Java datetime。这就是我决定ZoneDateTime适合我的原因。谢谢你的反馈。因此,我理解这一决定只是迁移的第一步,以避免在开始时进行过多重构。不过,您应该在中期考虑进一步的重构,因为代码易读性和维护在使用其他类型更容易理解和更合适的所有地方都受到使用<代码> ZONDATDATIMECT/<代码>的影响。
.parseDefaulting(ChronoField.YEAR_OF_ERA, ZonedDateTime.now().getYear())