Java Duration 类

Duration 是 Java 8 引入的 java.time 包中的核心类,用于精确表示基于时间的时间量(如秒、纳秒)。它专门处理小时、分钟、秒和纳秒级别的时间间隔,适合高精度时间计算。


核心特性
  1. 时间单位
    处理纳秒到天的转换(1 天 = 24 小时,不涉及日历日期)。
  2. 不可变且线程安全
    所有修改操作返回新实例。
  3. 精确到纳秒
    最高支持纳秒精度(1 秒 = 1,000,000,000 纳秒)。
  4. ISO-8601 标准兼容
    字符串格式为 PnDTnHnMn.nS(如 PT2H30M15.5S)。

使用场景
场景说明
计算代码执行时间测量方法运行耗时(替代 System.currentTimeMillis()
超时控制定义网络请求、任务执行的超时阈值
时间间隔计算计算两个时间点(如 Instant)之间的间隔
时间单位转换将分钟转换为秒、小时转换为纳秒等
调度任务定义任务之间的固定延迟(如 ScheduledExecutorService

关键 API 及用法
1. 创建 Duration 对象
// 通过时间单位创建
Duration d1 = Duration.ofSeconds(30);      // 30 秒
Duration d2 = Duration.ofMillis(500);      // 500 毫秒
Duration d3 = Duration.ofNanos(100_000);   // 100,000 纳秒

// 通过时间点计算
Instant start = Instant.now();
// ... 执行操作 ...
Instant end = Instant.now();
Duration elapsed = Duration.between(start, end);

// 解析字符串 (ISO-8601)
Duration d4 = Duration.parse("PT2H10M30.5S"); // 2小时10分30.5秒
2. 获取时间值
long seconds = d1.getSeconds();     // 总秒数(整数部分)
int nanos = d1.getNano();           // 纳秒部分(0~999,999,999)
long millis = d1.toMillis();        // 转换为毫秒(推荐替代 getNano())
3. 运算操作
Duration d5 = d1.plusMinutes(15);       // 增加 15 分钟
Duration d6 = d2.minusSeconds(10);       // 减去 10 秒
Duration d7 = d3.multipliedBy(2);       // 乘以 2
Duration d8 = d4.dividedBy(3);          // 除以 3
4. 比较与判断
boolean isZero = d1.isZero();            // 是否为零时长
boolean isNegative = d1.isNegative();    // 是否为负(当结束时间早于开始时间)
int compare = d1.compareTo(d2);          // 比较两个 Duration

完整案例演示
场景 1:计算代码执行时间
Instant start = Instant.now();
TimeUnit.SECONDS.sleep(2); // 模拟耗时操作
Instant end = Instant.now();

Duration duration = Duration.between(start, end);
System.out.println("执行耗时: " + duration.toMillis() + " 毫秒");
// 输出:执行耗时: 2000 毫秒
场景 2:定义任务超时阈值
Duration timeout = Duration.ofSeconds(5);
try {
    CompletableFuture.supplyAsync(() -> {
        try {
            TimeUnit.SECONDS.sleep(10); // 模拟超时任务
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        return "Result";
    }).get(timeout.toMillis(), TimeUnit.MILLISECONDS); // 设置超时
} catch (TimeoutException e) {
    System.err.println("任务超时!");
}
场景 3:时间单位转换
Duration dailyWork = Duration.ofHours(8);
System.out.println("每日工作分钟数: " + dailyWork.toMinutes()); // 输出 480

Duration shortBreak = Duration.parse("PT15M");
System.out.println("休息秒数: " + shortBreak.getSeconds()); // 输出 900
场景 4:时间区间运算
Duration taskTime = Duration.ofMinutes(45);
Duration breakTime = Duration.ofMinutes(15);
Duration totalTime = taskTime.plus(breakTime);

System.out.println("总时间: " + totalTime.toMinutes() + " 分钟"); // 输出 60

注意事项
  1. 日期无关性
    Duration 仅处理时间量,若需处理日历日期(如月、年),使用 Period 类。
  2. 负值处理
    end < start 时,Duration.between() 会产生负值,可通过 abs() 取绝对值。
  3. 精度损失
    toNanos()/toMillis() 可能导致溢出(Long.MAX_VALUE 约 292 年)。
  4. 替代 TimeUnit
    优先用 Duration 代替 TimeUnit 做时间运算(更直观且支持纳秒)。

总结

Duration 是处理精确时间间隔的理想工具,适用于:

  • 高精度计时(纳秒级)
  • 超时控制与调度
  • 时间单位转换
  • 时间区间运算

结合 InstantLocalTime 等时间类,可构建健壮的时间处理逻辑,彻底替代传统的 System.currentTimeMillis()Date 计算。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只帆記

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值