BleuBizarre
BleuBizarre

Reputation: 378

In PHP date->modify has a strange behavior

$start = $this->start; $start2 = $this->start; $start2 = $start2->modify('+1 hour');

Can someone explain me why $start is modified to and how to not modify it?

Upvotes: 1

Views: 67

Answers (2)

irjeffb
irjeffb

Reputation: 1

I was struggling with the same thing, and clone was the correct answer! (thank you, John)

// original
$pay_period_start = new DateTime('2021-04-21');
$pay_period_start_display_date = $pay_period_start->format('m-d-Y');
echo "Pay Period Start: ".$pay_period_start_display_date."<br>"; // outputs 04-21-2021 (correct)
$pay_period_end = $pay_period_start;
$pay_period_end->modify('+13 days');
$pay_period_end_display_date = $pay_period_end->format('m-d-Y');
echo "Pay Period End: ".$pay_period_end_display_date."<br>";  // outputs 05-04-2021 (correct)
$prev_pay_period_start = $pay_period_start;
$prev_pay_period_start->modify('-27 days'); // WHY did I have to go back 27 days instead of 14 ?!
$prev_pay_period_start_display_date = $prev_pay_period_start->format('m-d-Y');
echo "Prev Period Start: ".$prev_pay_period_start_display_date."<br>"; // outputs 04-07-2021 (correct)
$prev_pay_period_end = $prev_pay_period_start;
$prev_pay_period_end->modify('+13 days');
$prev_pay_period_end_display_date = $prev_pay_period_end->format('m-d-Y');
echo "Prev Period End: ".$prev_pay_period_end_display_date."<br>"; // outputs 04-20-2021 (correct)
// NOW, all dates are the same as the final one, even though they were saved to different variables
$pay_period_start_display_date = $pay_period_start->format('m-d-Y');
$pay_period_end_display_date = $pay_period_end->format('m-d-Y');
$prev_pay_period_start_display_date = $prev_pay_period_start->format('m-d-Y');
$prev_pay_period_end_display_date = $prev_pay_period_end->format('m-d-Y');
echo "<br>";
echo "Pay Period Start: ".$pay_period_start_display_date."<br>"; // outputs 04-20-2021
echo "Pay Period End: ".$pay_period_end_display_date."<br>"; // outputs 04-20-2021
echo "Prev Period Start: ".$prev_pay_period_start_display_date."<br>"; // outputs 04-20-2021
echo "Prev Period End: ".$prev_pay_period_end_display_date."<br>"; // outputs 04-20-2021

// with clone
echo "<br><br>";
$pay_period_start = new DateTime('2021-04-21');
$pay_period_end = clone $pay_period_start;
$prev_pay_period_start = clone $pay_period_start;
$prev_pay_period_end = clone $pay_period_start;
$pay_period_start_display_date = $pay_period_start->format('m-d-Y');
echo "Pay Period Start: ".$pay_period_start_display_date."<br>"; // outputs 04-21-2021 (correct)
$pay_period_end->modify('+13 days');
$pay_period_end_display_date = $pay_period_end->format('m-d-Y');
echo "Pay Period End: ".$pay_period_end_display_date."<br>";  // outputs 05-04-2021 (correct)
$prev_pay_period_start->modify('-14 days'); 
$prev_pay_period_start_display_date = $prev_pay_period_start->format('m-d-Y');
echo "Prev Period Start: ".$prev_pay_period_start_display_date."<br>"; // outputs 04-07-2021 (correct)
$prev_pay_period_end->modify('-1 days');
$prev_pay_period_end_display_date = $prev_pay_period_end->format('m-d-Y');
echo "Prev Period End: ".$prev_pay_period_end_display_date."<br>"; // outputs 04-20-2021 (correct)
$pay_period_start_display_date = $pay_period_start->format('m-d-Y');
$pay_period_end_display_date = $pay_period_end->format('m-d-Y');
$prev_pay_period_start_display_date = $prev_pay_period_start->format('m-d-Y');
$prev_pay_period_end_display_date = $prev_pay_period_end->format('m-d-Y');
echo "<br>";
echo "Pay Period Start: ".$pay_period_start_display_date."<br>"; // outputs 04-21-2021 (correct)
echo "Pay Period End: ".$pay_period_end_display_date."<br>"; // outputs 05-04-2021 (correct)
echo "Prev Period Start: ".$prev_pay_period_start_display_date."<br>"; // outputs 04-07-2021 (correct)
echo "Prev Period End: ".$prev_pay_period_end_display_date."<br>"; // outputs 04-20-2021 (correct)

Upvotes: 0

John Conde
John Conde

Reputation: 219844

Both $start and $start2 point to the same object. When you copy an object it copies by reference by default. To avoid this you need to clone instead:

$start = $this->start;
$start2 = clone $this->start;
$start2 = $start2->modify('+1 hour');

Upvotes: 4

Related Questions