php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #81651 In a for loop using dates, a date modify also updates the initial variable
Submitted: 2021-11-23 05:14 UTC Modified: 2021-11-23 07:03 UTC
From: cliffie dot baker at gmail dot com Assigned:
Status: Not a bug Package: Date/time related
PHP Version: 7.4.26 OS: Windows 10
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: cliffie dot baker at gmail dot com
New email:
PHP Version: OS:

 

 [2021-11-23 05:14 UTC] cliffie dot baker at gmail dot com
Description:
------------
Using a for loop to generate a range of dates and using the date modify to do the increment, the initial variable used for the start date is also being updated. I don't think this is the correct behaviour and certainly isn't consistent with a simple for loop.

Must admit I haven't tested in PHP 7.4.26 but have in 7.4.25

Tested using the 7.4.25 version of Xampp environment and also the 'try it' feature of the w3schools

Test script:
---------------
$start_date = new datetime('first Monday of January 2022');
$end_date = new datetime('last Monday of January 2022');

for ($date1 = $start_date; $date1 <= $end_date; $date1->modify('+1 week')) {
    echo $date1->format('Y-m-d').'<br>';
    }

echo 'Start date '. $start_date->format ('Y-m-d');

Gives
2022-01-03
2022-01-10
2022-01-17
2022-01-24
2022-01-31
Start date 2022-02-07

The original start date of 2022-01-03 has been updated to 2022-02-07 through the loop

Compare this to a simple for loop

$start = 5;

for ($x = $start; $x <= 10; $x++) {
  echo "The number is: $x <br>";
}
echo 'start '.$start;
?>  

Gives

The number is: 5
The number is: 6
The number is: 7
The number is: 8
The number is: 9
The number is: 10
start 5

This is as expected  

Expected result:
----------------
Should be -
For a for loop with date modify
Start 2022-01-03 (the original value)

Actual result:
--------------
Actual
For a for loop with date modify
Start date 2022-02-07 (the updated value at the end of the loop)

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2021-11-23 06:15 UTC] requinix@php.net
-Status: Open +Status: Not a bug
 [2021-11-23 06:15 UTC] requinix@php.net
There's a pretty big difference between the number 5 and an instance of the DateTime object. For example, one is a number and the other is an object.

$date1 and $start_date are going to be the same object because that is how objects work in PHP: assignment does not create copies. If you want $date1 and $start_date to be two different objects then they need to be two different objects.

You can do that by cloning $start_date into $date1.
https://www.php.net/manual/en/language.oop5.cloning.php

But don't do that here. Instead of a for loop and DateTime::modify, use a foreach loop and DatePeriod.
https://www.php.net/manual/en/class.dateperiod.php
 [2021-11-23 07:03 UTC] cliffie dot baker at gmail dot com
Thanks for the prompt response. I will try your suggestion.
Sorry for the newbie question

Thank you very much.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Mon Dec 30 14:01:28 2024 UTC