对LocalDate加减同一java.time.Period后结果不符预期问题咨询
这是预期行为,并非Java时间API的Bug
核心原因
Period是日历驱动的周期,它由年、月、日三个独立的日历单位组成,并非固定不变的绝对时长(比如1年可能是365或366天,取决于是否为闰年)。对LocalDate进行Period加减时,会严格按照年→月→日的顺序执行调整,而由于不同年份的天数存在差异(闰年/平年),导致"先减后加"或"先加后减"的操作无法保证对称,自然也就无法回到初始日期。
结合你的代码示例分析
你的period本质是P1Y365D(1年 + 365天),以下是具体场景的执行逻辑:
场景1:初始日期为2020-04-24(闰年)
- dateA2 = dateA.minus(period).plus(period)
- 先减
period:先减1年得到2019-04-24(平年),再减365天得到2018-04-24 - 再加
period:先加1年回到2019-04-24,再加365天——由于2019到2020年包含闰年2月,2019-04-24加365天实际是2020-04-23(比初始日期少1天)
- 先减
- dateA3 = dateA.plus(period).minus(period)
- 先加
period:先加1年得到2021-04-24(平年),再加365天得到2022-04-24 - 再减
period:先减1年回到2021-04-24,再减365天——2021到2020年是平年,刚好回到2020-04-24
- 先加
场景2:初始日期为2022-04-24(平年)
- dateB2 = dateB.minus(period).plus(period)
- 先减
period:先减1年得到2021-04-24(平年),再减365天得到2020-04-24 - 再加
period:先加1年回到2021-04-24,再加365天——2021到2022年是平年,刚好回到2022-04-24
- 先减
- dateB3 = dateB.plus(period).minus(period)
- 先加
period:先加1年得到2023-04-24(平年),再加365天得到2024-04-24(闰年) - 再减
period:先减1年回到2023-04-24,再减365天——2023到2022年是平年,最终得到2022-04-23(比初始日期少1天)
- 先加
解决方案
如果需要保证加减同一周期后严格回到初始日期,应该使用基于绝对时长的类或方法:
- 若仅涉及天数计算,直接使用
LocalDate.plusDays()/minusDays(),比如用plusDays(365 + 365)替代Period的组合 - 若需要处理更长的绝对时长,使用
Duration(适用于时分秒级)或ChronoUnit的固定单位计算
内容的提问来源于stack exchange,提问作者Florian
相关产品推荐
相关产品推荐

