Duration适用于同类型时间点(Instant或LocalTime)间的纯时间差计算:Instant适合跨时区精确耗时,LocalTime限于同日时间差;LocalDateTime等需转Instant再计算,含日期差异应优先用Period。

Java 中使用 Duration 类计算两个时间差,核心是:它只适用于**时间点之间相差的纯时间长度(如秒、毫秒、小时等)**,且要求这两个时间点必须是同一种“时间量纲”——即都得是 Instant、LocalTime 或 Temporal 的子类(但不能混用,比如不能拿 LocalDateTime 和 Instant 直接算 Duration)。
用 Instant 计算精确的时间差(推荐用于跨时区或系统时间)
Instant 表示时间线上的一个瞬时点(UTC 纳秒级),最适配 Duration。适合记录操作耗时、计算服务响应时间等。
示例:
Instant start = Instant.now(); // 执行一些操作... Thread.sleep(1234); Instant end = Instant.now(); Duration duration = Duration.between(start, end); System.out.println(duration.toMillis()); // 输出约 1234 毫秒 System.out.println(duration.getSeconds()); // 秒数(向下取整) System.out.println(duration.getNano()); // 剩余纳秒(0–999,999,999)
用 LocalTime 计算一天内的时间差(不涉及时区和日期)
如果只关心“上午 9:30 到下午 5:45 相差多久”,且不跨天、不考虑日期变化,可用 LocalTime。注意:它不能处理跨日(如 23:00 到次日 01:00),那样会抛 DateTimeException。
立即学习“Java免费学习笔记(深入)”;
示例:
LocalTime start = LocalTime.of(9, 30); LocalTime end = LocalTime.of(17, 45); Duration duration = Duration.between(start, end); // 得到 PT8H15M System.out.println(duration.toHours()); // 8 System.out.println(duration.toMinutes()); // 495 System.out.println(duration.toString()); // PT8H15M(ISO-8601 格式) </font> <H3>注意不能直接用 LocalDateTime 或 ZonedDateTime 算 Duration</H3> <p><code>Duration.between()</code> 接收两个 <code>Temporal</code> 参数,但 <code>LocalDateTime</code> 是“本地日期+时间”,不含时区信息,也不代表绝对时间点;直接用它算 <code>Duration</code> 虽然语法通过,但逻辑上容易出错(比如忽略夏令时、跨月天数不一致等)。</p> <p>正确做法是:如需含日期的时长(例如“从 2024-03-01 10:00 到 2024-03-05 14:30”),应优先考虑 <code>Period</code>(按年月日计算);若坚持用 <code>Duration</code>,先转成 <code>Instant</code>(需指定时区):</p> <font color="gray"> <pre class="brush:php;toolbar:false;"> LocalDateTime startLdt = LocalDateTime.of(2024, 3, 1, 10, 0); LocalDateTime endLdt = LocalDateTime.of(2024, 3, 5, 14, 30); ZoneId zone = ZoneId.systemDefault(); Instant start = startLdt.atZone(zone).toInstant(); Instant end = endLdt.atZone(zone).toInstant(); Duration d = Duration.between(start, end); // 得到总毫秒数对应的 Duration
常用 Duration 操作和格式化技巧
Duration 是不可变对象,支持加减、比较、转换单位,也支持解析 ISO-8601 字符串(如 P2DT3H4M)。
- 创建固定时长:
Duration.ofHours(2)、Duration.of(30, ChronoUnit.SECONDS) - 判断是否为正:
duration.isNegative()、duration.isZero() - 安全获取总秒数:
duration.toSecondsPart()(秒部分,0–59)、duration.toTotalNanos()(总纳秒,慎用可能溢出) - 格式化输出(需手动拼接):
String.format("%d h %d m %d s", d.toHours(), d.toMinutesPart(), d.getSecondsPart())


















