PHP:如何对DateTime::diff生成的DateInterval对象进行时间增减?
DateInterval 无法使用sub/modify方法的解决方案
问题本质
DateInterval类本身没有sub()和modify()这两个方法——这俩是DateTime类的专属方法,直接在DateInterval实例上调用肯定会报“未定义方法”的错。
正确调整DateInterval的三种方案
方案1:调整原DateTime后重新计算间隔
既然间隔是两个DateTime的差值,最稳妥的方式是先修改其中一个DateTime对象,再重新计算diff:
$d1 = "2024-01-01 00:00"; $d2 = date('Y-m-d H:i'); $dt1 = new DateTime($d1); $dt2 = new DateTime($d2); // 给dt2减去1小时,再重新计算间隔 $dt2->sub(new DateInterval('PT1H')); $interval = $dt1->diff($dt2);
方案2:直接修改DateInterval的公开属性
DateInterval的所有时间单位属性(比如h代表小时、m代表分钟、days代表天数)都是公开的,可以直接修改,但要手动处理借位逻辑:
$d1 = "2024-01-01 00:00"; $d2 = date('Y-m-d H:i'); $dt1 = new DateTime($d1); $dt2 = new DateTime($d2); $interval = $dt1->diff($dt2); // 给间隔减去1小时,处理借位 if ($interval->h >= 1) { $interval->h -= 1; } else { // 小时不够减,从天数借1天(24小时) if ($interval->days > 0) { $interval->days -= 1; $interval->h += 23; } else { // 若天数也为0,说明原间隔不足1小时,可按需处理 $interval->h = 0; // 如果需要表示负间隔,设置invert属性为1(0为正,1为负) $interval->invert = 1; } }
这种方法适合低版本PHP,但要注意不同单位间的借位(比如分钟不够减要从小时扣,小时不够从天数扣),否则会得到错误的间隔值。
方案3:借助DateTime中转调整(PHP 8.3+)
PHP 8.3新增了DateInterval::createFromDateTime()方法,可以把间隔转换为DateTime对象,调整后再转回DateInterval,不用手动处理借位:
$d1 = "2024-01-01 00:00"; $d2 = date('Y-m-d H:i'); $dt1 = new DateTime($d1); $dt2 = new DateTime($d2); $interval = $dt1->diff($dt2); // 把间隔转为基于Unix纪元的DateTime $tempDt = DateInterval::createFromDateTime($interval); // 减去1小时 $tempDt->sub(new DateInterval('PT1H')); // 转回DateInterval $adjustedInterval = (new DateTime())->diff($tempDt);
内容的提问来源于stack exchange,提问作者user1719210
相关产品推荐
相关产品推荐

