Duration 与 Period
两个时间间隔类
JDK 8+ 提供了两个处理时间间隔的类:
- Duration:基于时间的间隔(时、分、秒、纳秒)
- Period:基于日期的间隔(年、月、日)
它们回答的是不同的问题:Duration 回答「过了多久」,Period 回答「相隔多少天/月/年」。
Duration:时间间隔
用于秒、纳秒级别的时间度量,适合计算执行时间、session 超时等。
创建
java
Duration oneHour = Duration.ofHours(1);
Duration thirtyMinutes = Duration.ofMinutes(30);
Duration oneMinute = Duration.ofSeconds(60);
Duration twoSeconds = Duration.ofSeconds(2);
Duration oneSecond = Duration.ofSeconds(1, 0);
Duration fiveHundredMillis = Duration.ofMillis(500);
// 从两个 Instant 创建
Instant start = Instant.now();
// ... some work ...
Instant end = Instant.now();
Duration elapsed = Duration.between(start, end);计算
java
Duration d = Duration.ofHours(2).plusMinutes(30); // 2.5 小时
// 加减
Duration plus = d.plusMinutes(10); // 增加 10 分钟
Duration minus = d.minusHours(1); // 减少 1 小时
Duration multiplied = d.multipliedBy(2); // 乘以 2
Duration divided = d.dividedBy(2); // 除以 2
// 取反
Duration negated = d.negated(); // 变成 -2.5 小时获取值
java
Duration d = Duration.ofHours(2).plusMinutes(30).plusSeconds(45);
d.toDays(); // 0 天
d.toHours(); // 2 小时
d.toMinutes(); // 150 分钟
d.toSeconds(); // 9045 秒
d.toMillis(); // 9045000 毫秒
d.toNanos(); // 9045000000000 纳秒
d.getSeconds(); // 9045 秒(总秒数,不含更高单位)
d.getNano(); // 0 纳秒(秒以下的余数)判断
java
Duration oneHour = Duration.ofHours(1);
Duration twoHours = Duration.ofHours(2);
oneHour.isNegative(); // false
oneHour.isZero(); // false
oneHour.compareTo(twoHours); // -1,oneHour < twoHoursPeriod:日期间隔
用于年、月、日的度量,适合计算年龄、日历日期差等。
创建
java
// 直接创建
Period oneYear = Period.ofYears(1);
Period twoMonths = Period.ofMonths(2);
Period threeDays = Period.ofDays(3);
// 组合
Period period = Period.of(1, 2, 3); // 1 年 2 月 3 天
// 从两个 LocalDate 创建
LocalDate start = LocalDate.of(2026, 1, 1);
LocalDate end = LocalDate.of(2026, 3, 22);
Period between = Period.between(start, end); // P2M21D(2个月21天)计算
java
Period p = Period.of(1, 2, 3); // 1年2月3天
// 加减
Period plus = p.plusDays(5); // 1年2月8天
Period minus = p.minusMonths(1); // 1年1月3天
Period multiplied = p.multipliedBy(2); // 2年4月6天
// 规范化(转为标准形式)
Period normalized = Period.of(0, 14, 0).normalized(); // P1Y2M获取值
java
Period p = Period.of(1, 2, 3);
p.getYears(); // 1
p.getMonths(); // 2
p.getDays(); // 3
p.toTotalDays(); // 456 天(粗略估算)实际应用
计算程序执行时间
java
Instant start = Instant.now();
// ... 要测量的代码 ...
Instant end = Instant.now();
Duration elapsed = Duration.between(start, end);
System.out.println("耗时: " + elapsed.toMillis() + " ms");session 超时判断
java
Instant lastAccess = Instant.now().minusSeconds(1800); // 30 分钟前
Duration timeout = Duration.ofMinutes(30);
boolean expired = Duration.between(lastAccess, Instant.now()).compareTo(timeout) > 0;计算年龄
java
public static int calculateAge(LocalDate birthDate) {
return Period.between(birthDate, LocalDate.now()).getYears();
}计算距离某日还有多少天
java
LocalDate today = LocalDate.now();
LocalDate target = LocalDate.of(2026, 12, 31);
Period remaining = Period.between(today, target);
System.out.println("还有 " + remaining.getMonths() + " 个月 " + remaining.getDays() + " 天");Duration vs Period
| 方面 | Duration | Period |
|---|---|---|
| 基础单位 | 秒/纳秒 | 年/月/日 |
| 适用场景 | 执行时间、超时 | 年龄、日历计算 |
| 和 Instant | 配合好 | 配合 LocalDate |
| 夏令时 | 不受影响 | 可能受影响 |
| 精度 | 纳秒 | 天 |
总结
- Duration:时间轴上的长度,适合计算「过去了多久」
- Period:日历上的跨度,适合计算「相隔多少天/月/年」
记住:Duration 基于时间线(秒),Period 基于日历(年月日)。
