我正在尝试使用date_add
和date_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
答案 0 :(得分:5)
当你这样做时:
$tempy = $y;
您创建了对第一个对象的伪引用,您实际上并未复制它。为此,您需要使用clone
关键字:
$tempy = clone $y;
现在事情会像你期望的那样奏效。如果没有克隆,当您修改$tempy
时,它也会修改$y
编辑:添加关于此的手册链接(来自@ Devon的回答)http://php.net/manual/en/language.oop5.references.php
答案 1 :(得分:0)
您只创建了一个对象(使用new DateTime
完成),因此无论您如何引用它,所有对它们的操作(子和添加)都在该对象上完成。
答案 2 :(得分:0)
这不是错误,这是预期的结果。阅读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天的时间了。唯一的区别是导出格式化日期时。
答案 3 :(得分:0)
我认为您遇到的错误是您重复使用原始$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,因此我使用的是OO等价物而不是date_format
。