period.between() 计算 localdate 间年月日差基于日历单位逐级相减,非总天数折算;结果为逻辑日历差,如 2023-01-15 至 2024-03-20 得 1年2个月5天;起始日期在前、结束日期在后,逆序则各字段为负;遵循月份长度与闰年规则对齐,不简单按30天/月换算;需总天数等应改用 chronounit;getdays() 始终在 0–30 范围内。

Java 中用 Period.between() 计算两个 LocalDate 之间的年、月、日差,本质是按“日历单位”逐级相减(先算年,再算月,最后算日),不是简单换算成总天数再折算。结果是逻辑上的“日历差”,比如 2023-01-15 到 2024-03-20 是 1 年 2 个月 5 天,而不是按 365+65=430 天反推。
使用 Period.between() 获取年月日差
直接调用静态方法 Period.between(startDate, endDate),参数顺序很重要:前者是起始日期,后者是结束日期。若结束日期早于起始日期,返回的 Period 中各字段为负值。
Period period = Period.between(LocalDate.of(2022, 5, 10), LocalDate.of(2024, 8, 25));- 结果:
period.getYears()→ 2,period.getMonths()→ 3,period.getDays()→ 15 - 即:2 年 3 个月 15 天
注意“日历对齐”带来的非直观结果
计算不基于总天数,而是按月份长度和闰年规则“对齐”推算。例如:
-
Period.between(LocalDate.of(2023, 1, 31), LocalDate.of(2023, 3, 3))→ 1 个月 1 天(不是 31 天 ÷ 30 ≈ 1.03 个月) - 原理:从 1 月 31 日加 1 个月得 2 月 28 日(2023 非闰年),再加 1 天到 3 月 1 日,还需 2 天到 3 月 3 日?不对——实际算法是“尝试增加年/月使日期逼近终点”,最终得出 1 个月 + 1 天(因为 2 月没有 31 日,自动回退到当月最后一天)
- 更稳妥的理解方式:它模拟人工翻日历——先加整年,再加整月,最后补天数
获取总天数或其它单位需另用 ChronoUnit
如果需要总天数、小时或工作日等,Period 不适用,应改用 ChronoUnit:
- 总天数:
long days = ChronoUnit.DAYS.between(start, end); - 总月数(按 30.44 天近似):
long months = ChronoUnit.MONTHS.between(start, end);(注意:这是按日历月数,非 Period 的“可加性月数”) - 不支持直接算工作日,需配合 TemporalAdjusters 或第三方库(如 ThreeTen-Extra)
格式化输出与边界情况处理
打印时建议用 Period.toString()(如 P2Y3M15D),或手动拼接提升可读性:
String.format("%d年%d月%d天", p.getYears(), p.getMonths(), p.getDays())- 注意:
getDays()永远在 0–30 范围内,不会出现 45 天;超过 30 天会进位到getMonths() - 若两日期相同,返回
P0D,所有字段为 0 - 跨闰年(如 2023-02-28 到 2024-02-29)也能正确识别多出的一天
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











