Reputation: 473
I am trying to add and subtract # of days to a date using date_add
and date_sub
, but I get some weird results. I assume this is an easy answer I am just not versed enough in PHP to know why.
Here is my code:
$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";
This is the result:
Start: 2016-05-10 End: 2016-05-17
It looks like even though I use a temporary variable $tempy
for the start date it still modifies it and the end date is off.
EDIT: Expected results:
Start: 2016-05-10 End: 2016-05-24
Upvotes: 0
Views: 1126
Reputation: 11494
I think the mistake you were having is that you re-used your original $date
with the assumption its state would not change. I've also refactored your code a little. In the time it's taken me to write this several answers have been posted, but I'll leave it if my example is easier to follow for some.
$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;
You'll notice on PHP.net docs that there are often interchangeable procedural style functions and object oriented ones. Try to utilise the OO ones whenever possible, so instead of using date_format
, I used its OO equivalent.
Upvotes: 0
Reputation: 1237
When you do :
$tempy = $y;
You create a pseudo reference to the first object, you don't actually copy it. To do so you need to use the clone
keyword :
$tempy = clone $y;
Now things will work as you expect. Without cloning, when you modify $tempy
it will also modify $y
EDIT : Adding link to manual about this (from @Devon's answer) http://php.net/manual/en/language.oop5.references.php
Upvotes: 5
Reputation: 35337
This isn't a bug, this is an expected result. Read up on http://php.net/manual/en/language.oop5.references.php
$tempy = $y;
$tempy->sub(new DateInterval('P' . $z2 . 'D'));
At this point, both $tempy and $y have had 7 days subtracted because they point to the same instance.
$y->add(new DateInterval('P' . $z2 . 'D'));
Now both have had 7 days added back to it. The only difference being when you export the formatted date.
Upvotes: 0
Reputation:
You have only created one object (done with new DateTime
), so all your operations on them (sub and add) are done on that one object regardless of how you reference it.
Ref: http://php.net/manual/en/language.oop5.references.php
Upvotes: 0