PHP 8.6 新增 Time\Duration 与 clamp():纳秒时长运算和边界收敛
PHP 8.6 计划 2026 年 11 月 19 日 GA,截至 2026-09-24 处于 8.6.0RC2,共有 27 个 RFC 被接受。其中两个会直接出现在日常业务代码里:Time\Duration 时长类型,以及全局函数 clamp()。
Time\Duration:纳秒精度的时长类型
Time\Duration 是一个 final、readonly 的时长类型,精度到纳秒。它表示的是“一段时长”,不是时间轴上的某个点,因此和 DateTimeImmutable 这类日期时间对象分工不同:前者用于耗时、间隔、超时预算,后者用于具体时刻。
构造入口有两类:
- 工厂方法,覆盖从秒到纳秒的各档单位;
- ISO 8601 字符串。
具体方法名与完整签名以 RFC 页面为准,整体用法大致如下:
use Time\Duration;
$seconds = Duration::fromSeconds(2);
$millis = Duration::fromMilliseconds(500);
$micros = Duration::fromMicroseconds(250);
$nanos = Duration::fromNanoseconds(1);
// 从 ISO 8601 字符串构造
$iso = Duration::fromIso8601String('PT1H30M');
// 加减
$total = $seconds->add($iso);
$rest = $total->sub(Duration::fromSeconds(1));
// 乘除
$triple = $seconds->multiplyBy(3);
$half = $seconds->divideBy(2);
// 比较运算符
if ($half < $seconds) {
// ...
}
除了 add() / sub() / multiplyBy() / divideBy(),该类型也支持比较运算符,所以排序、取最小值这类操作不需要先手工换算成整数。
它的取值范围约为 292 年,并且是溢出安全的:超出范围不会被静默截断或回绕,这一点在累计耗时、长周期调度预算的场景里比裸整数更重要。292 年大致对应纳秒计数在 64 位有符号整数下的上限,对绝大多数业务来说够用,但如果你要做“从纪元开始的纳秒偏移”这类极端计算,仍然需要自己确认一下边界。
选择它的理由主要是省掉单位换算。以前记录耗时常见写法是 microtime(true) 相减得到浮点秒数,再乘 1000 或 1e6,单位信息只存在于变量名和注释里;换成 Duration 之后,单位随对象走,加法减法也不会因为混用毫秒和秒而出错。代价是多了一层对象,在高频循环里做纯数值统计时,整数运算依然更轻。
clamp():边界收敛的全局函数
新增的全局函数 clamp($value, $min, $max) 把常见的区间限制写法收进一次调用:
$ratio = clamp($ratio, 0.0, 1.0);
$percent = clamp($percent, 0, 100);
$timeout = clamp($timeout, 1, 30);
它替代的是这些重复形态:
$percent = max(0, min(100, $percent));
$percent = $percent < 0 ? 0 : ($percent > 100 ? 100 : $percent);
取舍很直接:值本身是数字、区间是固定上下界时,clamp() 更短也更难写错,尤其是上界和下界容易在 min() / max() 嵌套里写反。反过来,如果边界来自对象、需要自定义比较逻辑,或者要区分“低于下界”和“高于上界”分别处理,clamp() 就只能退化成一次判断,仍然得自己写分支。
其他已接受的 RFC
同一批被接受的改动还包括:readonly 属性默认值、#[Override] 用于类常量、DocComments for Function Parameters、无状态闭包缓存(stateless closures are cached)、结构化 stream 错误、Polling API(Io\Poll)、ext/uri builders 与类型检测、enum SortDirection、pack() / unpack() 端序修饰符、mysqli::quote_string()。
链接
Time\DurationRFC:https://wiki.php.net/rfc/duration_classclamp()RFC:https://wiki.php.net/rfc/clamp_v2- PHP 官网:https://www.php.net/