You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP 8.1中date_modify返回负微秒问题求助

PHP 8.1负微秒日期时间异常的原因解析

这个问题是PHP 8.1版本中DateTime类处理毫秒减法时的精度计算bug,仅在特定条件下触发:当原时间的微秒值极小(如1微秒),且执行的减法操作会导致微秒部分出现负数时,DateTime内部未正确执行向秒位的借位修正逻辑。

具体触发逻辑拆解

  1. 当DateTime对象的微秒设为1(即0.000001秒),执行modify('-100 ms')时,实际是减去0.1秒(等于100000微秒)。
  2. 计算时微秒部分直接得到1 - 100000 = -99999,而正常逻辑中,这种负数微秒应该触发向秒位借1:秒数减1,微秒部分加上1000000(1秒对应的微秒数),最终得到01:01:00.900001。
  3. 但PHP 8.1的DateTime未处理这个借位,直接保留了负的微秒值,导致用u格式化符输出时出现.-99999的异常结果。

验证代码及异常输出

触发问题的测试代码:

$datetime_before = date_create('now');
$datetime_before->setTime(1,1,1,1); // 微秒设为1时触发bug
$datetime_after  = clone($datetime_before);
$datetime_after->modify('-100 ms');
$string   = $datetime_after->format('Y-m-d H:i:s.u');
if (str_contains($string, "-999")) {
    echo 'before: ';
    var_dump($datetime_before);
    echo PHP_EOL;
    echo 'after: ';
    var_dump($datetime_after);
    echo PHP_EOL;
    exit;
}

异常输出:

before: object(DateTime)#51 (3) { ["date"]=> string(26) "2023-06-02 01:01:01.000001" ["timezone_type"]=> int(3) ["timezone"]=> string(13) "Europe/London" }
after: object(DateTime)#52 (3) { ["date"]=> string(26) "2023-06-02 01:01:01.-99999" ["timezone_type"]=> int(3) ["timezone"]=> string(13) "Europe/London" }

版本修复情况

该bug已在PHP 8.2及后续版本中被修复,相同代码在高版本PHP中会输出正确的日期时间字符串。

内容的提问来源于stack exchange,提问作者Adam Edney

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 01:58:16