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

PHP <8.2与8.2+双减号日期修改符差异及变更说明咨询

PHP 8.2中strtotime/DateTime::modify处理双减号日期表达式的行为变化问题

问题根源

当$index为负数时,拼接后的日期表达式会出现连续双减号(例如"2021-07-05 --1 day")。PHP 7.4及更早版本会将这类表达式解析为等价于加号(即"+1 day"),而PHP 8.2中则严格解析为两次减法(最终效果为"-1 day"),导致时间戳计算结果完全相反。

为什么官方变更日志未提及?

这个行为变化并非PHP核心语法变更,而是底层依赖的timelib(PHP日期处理的核心库)在版本迭代中修正了表达式解析逻辑,对连续符号的处理更加严格。这类依赖库的细节调整通常不会单独出现在PHP官方ChangeLog中,而是包含在日期组件的整体更新里。

临时修复方案(无需彻底重构)

避免生成带双重符号的字符串表达式,改用更明确的日期操作方式:

方案1:使用DateTime对象的偏移量计算

public static function getCorrectedTime(
    int $year,
    int $month,
    int $day,
    int $index,
    string $period
): int {
    $date = new DateTime("{$year}-{$month}-{$day}");
    // 原逻辑等价于:减去 $index 个周期,index为负时相当于加上其绝对值的周期
    $offset = -$index;
    // 根据实际支持的周期类型匹配DateInterval格式
    $intervalSpec = match(strtolower($period)) {
        'day' => "P{$offset}D",
        'hour' => "PT{$offset}H",
        'minute' => "PT{$offset}M",
        default => throw new InvalidArgumentException("Unsupported period: {$period}"),
    };
    $date->add(new DateInterval($intervalSpec));
    return $date->getTimestamp();
}

方案2:提前处理符号,避免双重减号

public static function getCorrectedTime(
    int $year,
    int $month,
    int $day,
    int $index,
    string $period
): int {
    // 明确生成带单个符号的合法表达式
    $sign = $index >= 0 ? '-' : '+';
    $absIndex = abs($index);
    $timestamp = strtotime("{$year}-{$month}-{$day} {$sign}{$absIndex} {$period}");
    return $timestamp;
}

两种方案都能在PHP 7.4和8.2中保持一致的计算逻辑,无需彻底重构现有代码结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 09:02:44