PHP - 使用 DateInterval 添加和减去天数的奇怪错误

PHP - Adding and Subtracting Days Weird Bug with DateInterval

我正在尝试使用 date_adddate_sub 对日期添加和减去天数,但我得到了一些奇怪的结果。我认为这是一个简单的答案,我只是对 PHP 不够熟悉,不知道为什么。

这是我的代码:

$y = new DateTime('2016-05-17');
$z2 = 7;
$tempy = $y;
$tempy->sub(new DateInterval('P' . $z2 . 'D'));
$startdate = date_format($tempy, "Y-m-d");
$y->add(new DateInterval('P' . $z2 . 'D'));
$enddate = date_format($y, "Y-m-d");
echo "Start: " . $startdate . "  End: " . $enddate . "\r\n";

这是结果:

Start: 2016-05-10 End: 2016-05-17

看起来即使我使用临时变量 $tempy 作为开始日期它仍然会修改它并且结束日期已关闭。

编辑: 预期结果:

Start: 2016-05-10 End: 2016-05-24

您只创建了一个对象(使用 new DateTime 完成),因此无论您如何引用它,您对它们的所有操作(子和添加)都是在该对象上完成的。

参考:http://php.net/manual/en/language.oop5.references.php

当你这样做时:

$tempy = $y;

您创建了对第一个对象的伪引用,实际上并没有复制它。为此,您需要使用 clone 关键字:

$tempy = clone $y;

现在一切都会如您所愿。没有克隆,当你修改 $tempy 它也会修改 $y

编辑:将 link 添加到手册中(来自@Devon 的回答)http://php.net/manual/en/language.oop5.references.php

这不是错误,这是预期结果。继续阅读 http://php.net/manual/en/language.oop5.references.php

$tempy = $y;
$tempy->sub(new DateInterval('P' . $z2 . 'D'));

此时,$tempy 和 $y 都减去了 7 天,因为它们指向同一个实例。

$y->add(new DateInterval('P' . $z2 . 'D'));

现在两者都增加了 7 天。唯一的区别是当您导出格式化日期时。

我认为您犯的错误是您在假设其状态不会改变的情况下重新使用了原始 $date。我还稍微重构了您的代码。在我写这篇文章的时候,已经发布了几个答案,但如果我的例子对某些人来说更容易理解,我会留下它。

$date = new DateTime('2016-05-17');

$calculateBeforeDate = clone $date;
$calculateAfterDate = clone $date;


$startDate = $calculateBeforeDate->sub(new DateInterval('P7D'))->format('Y-m-d');

$endDate = $calculateAfterDate->add(new DateInterval('P7D'))->format('Y-m-d');

echo "Start: $startDate, End: $endDate" . PHP_EOL;

您会在 PHP.net 文档中注意到,通常存在可互换的过程样式函数和面向对象的函数。尽可能尝试使用 OO 的,所以我没有使用 date_format,而是使用它的 OO 等价物。