java.time.Period计算LocalDate间隔结果异常,求原因解释
关于java.time.Period计算日期间隔的异常现象解析
使用java.time.Period结合java.time.LocalDate计算日期间隔时,多数情况能得到符合预期的年、月、日形式间隔,但存在如下特殊案例:
测试代码
val test1 = LocalDate.of(2023, 1, 31) val test2 = LocalDate.of(2023, 1, 28) val testToday = LocalDate.of(2023, 3, 9) val period1 = Period.between(test1, testToday) val period2 = Period.between(test2, testToday) L.d { "test1 = $test1 | test2 = $test2 | today = $testToday" } L.d { "period1 = $period1 | period2 = $period2" }
输出结果
period1 = P1M9D | period2 = P1M9D test1 = 2023-01-31 | test2 = 2023-01-28 | today = 2023-03-09
疑问点
- 2023-01-31 到 2023-03-09 的间隔为1个月9天(P1M9D)
- 2023-01-28 到 2023-03-09 的间隔也为1个月9天(P1M9D)
按预期后者应比前者多3天,该现象的原因是什么?
原因解析
这是因为Period.between()的计算逻辑是优先按年、月、日的顺序计算差值,且处理跨月份时遵循「当月最后一天」的特殊适配规则:
针对
test1(2023-01-31)到testToday(2023-03-09):- 先增加1个月:2023-01-31 + 1个月 = 2023-02-28(2023年2月没有31日,自动调整为当月最后一天)
- 再增加9天:2023-02-28 + 9天 = 2023-03-09,刚好匹配目标日期,因此得到
P1M9D。
针对
test2(2023-01-28)到testToday(2023-03-09):- 先增加1个月:2023-01-28 + 1个月 = 2023-02-28
- 再增加9天:2023-02-28 + 9天 = 2023-03-09,同样匹配目标日期,所以结果也是
P1M9D。
本质上,Period的设计定位是处理人类日常认知中的「年月跨度」,而非精确的总天数差。如果需要获取两个日期之间的精确天数间隔,应该使用ChronoUnit.DAYS.between()方法,该方法会直接计算总天数:前者为37天,后者为40天,差值正好是3天。
内容的提问来源于stack exchange,提问作者prom85
相关产品推荐
相关产品推荐

