You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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()的计算逻辑是优先按年、月、日的顺序计算差值,且处理跨月份时遵循「当月最后一天」的特殊适配规则:

  1. 针对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。
  2. 针对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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 15:43:33