period用于localdate间日历差值计算,结果为年月日(如p3y4m13d),需先将string/instant/date转localdate,不可用于带时间类型,总天数应使用chronounit.days。

Java 中使用 Period 计算两个日期的年、月、日间隔,适用于 LocalDate 类型(不包含时间),结果是“日历意义上的差值”,即按年、月、日逐级进位(比如 1 年 = 12 个月,1 月 ≈ 30 天但实际按具体月份天数计算),不是总天数。
确保使用 LocalDate
Period 只支持 LocalDate。如果原始数据是 String、Instant 或 java.util.Date,需先转换:
- 字符串 →
LocalDate:LocalDate.parse("2022-03-15")(默认 ISO 格式)或指定格式器:LocalDate.parse("15/03/2022", DateTimeFormatter.ofPattern("dd/MM/yyyy")) -
Instant→LocalDate:需通过时区转换,例如 instant.atZone(ZoneId.systemDefault()).toLocalDate() -
java.util.Date→LocalDate:date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate()
用 Period.between() 获取年月日差
直接调用静态方法 Period.between(startDate, endDate),注意参数顺序:前者是起始日期,后者是结束日期;若起始晚于结束,返回的 Period 各字段为负值。
示例:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
LocalDate start = LocalDate.of(2021, 5, 15); LocalDate end = LocalDate.of(2024, 9, 28); Period period = Period.between(start, end); System.out.println(period); // P3Y4M13D(3年4个月13天)
可通过 getter 方法分别获取:
- period.getYears() → 3
- period.getMonths() → 4
- period.getDays() → 13
注意边界与逻辑含义
Period 是基于日历的“调整后差值”,不是简单相减:
- 它会自动处理月份天数差异(如从 1 月 31 日到 2 月 28 日,算作 1 个月,不是 -3 天)
- 不跨年时不会“借位”:2023-01-10 到 2023-03-05 是 P1M23D(1 个月 + 23 天),不是 0 年 1 个月 25 天(因为 2 月只有 28 天)
- 结果始终是最简日历表达:不会出现 P12M,而是自动转为 P1Y
避免常见误用
不要用 Period 计算带时间的差值(如 LocalDateTime),也不要用它替代总天数计算:
- 要总天数?用 ChronoUnit.DAYS.between(start, end)
- 要精确到时分秒?用 Duration(仅适用于
Instant或LocalTime等基于时间线的类型) - 跨时区或含夏令时场景?
Period仍适用(因只依赖日期,与时区无关),但输入的LocalDate必须已按业务时区对齐
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










