Skip to content

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 < twoHours

Period:日期间隔

用于年、月、日的度量,适合计算年龄、日历日期差等。

创建

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

方面DurationPeriod
基础单位秒/纳秒年/月/日
适用场景执行时间、超时年龄、日历计算
和 Instant配合好配合 LocalDate
夏令时不受影响可能受影响
精度纳秒

总结

  • Duration:时间轴上的长度,适合计算「过去了多久」
  • Period:日历上的跨度,适合计算「相隔多少天/月/年」

记住:Duration 基于时间线(秒),Period 基于日历(年月日)。

基于 VitePress 构建