[php-src] Issue #8275: Function strtotime("-x month", ...) returns different month if the date part is 01-28 or >=29. Additionally different
behaviour for leap and non-leap years
| From: | sathishpaniker | Date: | Wed, 30 Mar 2022 07:27:28 +0000 |
| Subject: | [php-src] Issue #8275: Function strtotime("-x month", ...) returns different month if the date part is 01-28 or >=29. Additionally different behaviour for leap and non-leap years |
||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-240565@lists.php.net to get a copy of this message | ||
Issue: https://github.com/php/php-src/issues/8275
Author: sathishpaniker
### Description
Date('Y-m-01', strtotime("-1 month", strtotime(Date("2022-03-28"))))
is returning '2022-02-01', but
Date('Y-m-01', strtotime("-1 month", strtotime(Date("2022-03-29"))))
is returning '2022-03-01'. This behaviour fails on different months and also based on year
is leap year or not. Hence, added a code which could cover all scenarios
The following code:
```php
<?php
function date_function_check($year, $month, $isleapyear) {
echo "\n\n========= ";
echo "Testing for YEAR = $year , which is" . (!$isleapyear ? " NOT" :
"") . " a Leap Year";
echo " ========\n";
// Loop through
for ($month = 1; $month <= 12; $month++) {
if (($month == 2) && (!$isleapyear)) { continue; } // skipiing as Feb has 28 todays
except for leap year
if ($month < 10) {$mn = "0" . $month; } else {$mn = "" . $month; }
// Create a date and time variable for day = 28
$day = '28';
$dta = Date($year . "-" . $mn . "-" . $day);
$tma = strtotime($dta);
// Create a date and time variable for day = 28
$day = '29';
$dtb = Date($year . "-" . $mn . "-" . $day);
$tmb = strtotime($dtb);
// Starting the test with the created reference dates
echo "\n\n $month. Performing TEST with dates as $dta and $dtb scenario";
// Get all last 12 months using Date("-x month", ...) date function
for ($i = 1; $i <= 12; $i++) {
$j = $i * -1;
$newdt1 = Date('Y-m-01', strtotime($j . " month", $tma));
$newdt2 = Date('Y-m-01', strtotime($j . " month", $tmb));
if ($newdt1 !== $newdt2) {
echo "\n Testing condition : \"" . $j . " month\" as
parameter";
echo "\n - If PHP statement : Date('Y-m-01', strtotime(\"" .
$j . " month\", strtotime(Date(\"" . $dta . "\"))))\n";
echo " Value returned is " . $newdt1 . "\n";
echo " - If PHP statement : Date('Y-m-01', strtotime(\"" .
$j . " month\", strtotime(Date(\"" . $dtb . "\"))))\n";
echo " Incorrect Date Value returned is " . $newdt2 . "
(Expected Date: " . $newdt1 . ")\n";
}
}
}
echo "\n";
}
// Main section
date_function_check('2022', 1, false); // Not a leap year
date_function_check('2024', 1, true); // Is a leap year
```
Resulted in this output:
```
========= Testing for YEAR = 2022 , which is NOT a Leap Year ========
1. Performing TEST with dates as 2022-01-28 and 2022-01-29 scenario
Testing condition : "-11 month" as parameter
- If PHP statement : Date('Y-m-01', strtotime("-11 month",
strtotime(Date("2022-01-28"))))
Value returned is 2021-02-01
- If PHP statement : Date('Y-m-01', strtotime("-11 month",
strtotime(Date("2022-01-29"))))
Incorrect Date Value returned is 2021-03-01 (Expected Date: 2021-02-01)
3. Performing TEST with dates as 2022-03-28 and 2022-03-29 scenario
Testing condition : "-1 month" as parameter
- If PHP statement : Date('Y-m-01', strtotime("-1 month",
strtotime(Date("2022-03-28"))))
Value returned is 2022-02-01
- If PHP statement : Date('Y-m-01', strtotime("-1 month",
strtotime(Date("2022-03-29"))))
Incorrect Date Value returned is 2022-03-01 (Expected Date: 2022-02-01)
4. Performing TEST with dates as 2022-04-28 and 2022-04-29 scenario
Testing condition : "-2 month" as parameter
- If PHP statement : Date('Y-m-01', strtotime("-2 month",
strtotime(Date("2022-04-28"))))
Value returned is 2022-02-01
- If PHP statement : Date('Y-m-01', strtotime("-2 month",
strtotime(Date("2022-04-29"))))
Incorrect Date Value returned is 2022-03-01 (Expected Date: 2022-02-01)
5. Performing TEST with dates as 2022-05-28 and 2022-05-29 scenario
Testing condition : "-3 month" as parameter
- If PHP statement : Date('Y-m-01', strtotime("-3 month",
strtotime(Date("2022-05-28"))))
Value returned is 2022-02-01
- If PHP statement : Date('Y-m-01', strtotime("-3 month",
strtotime(Date("2022-05-29"))))
Incorrect Date Value returned is 2022-03-01 (Expected Date: 2022-02-01)
6. Performing TEST with dates as 2022-06-28 and 2022-06-29 scenario
Testing condition : "-4 month" as parameter
- If PHP statement : Date('Y-m-01', strtotime("-4 month",
strtotime(Date("2022-06-28"))))
Value returned is 2022-02-01
- If PHP statement : Date('Y-m-01', strtotime("-4 month",
strtotime(Date("2022-06-29"))))
Incorrect Date Value returned is 2022-03-01 (Expected Date: 2022-02-01)
7. Performing TEST with dates as 2022-07-28 and 2022-07-29 scenario
Testing condition : "-5 month" as parameter
- If PHP statement : Date('Y-m-01', strtotime("-5 month",
strtotime(Date("2022-07-28"))))
Value returned is 2022-02-01
- If PHP statement : Date('Y-m-01', strtotime("-5 month",
strtotime(Date("2022-07-29"))))
Incorrect Date Value returned is 2022-03-01 (Expected Date: 2022-02-01)
8. Performing TEST with dates as 2022-08-28 and 2022-08-29 scenario
Testing condition : "-6 month" as parameter
- If PHP statement : Date('Y-m-01', strtotime("-6 month",
strtotime(Date("2022-08-28"))))
Value returned is 2022-02-01
- If PHP statement : Date('Y-m-01', strtotime("-6 month",
strtotime(Date("2022-08-29"))))
Incorrect Date Value returned is 2022-03-01 (Expected Date: 2022-02-01)
9. Performing TEST with dates as 2022-09-28 and 2022-09-29 scenario
Testing condition : "-7 month" as parameter
- If PHP statement : Date('Y-m-01', strtotime("-7 month",
strtotime(Date("2022-09-28"))))
Value returned is 2022-02-01
- If PHP statement : Date('Y-m-01', strtotime("-7 month",
strtotime(Date("2022-09-29"))))
Incorrect Date Value returned is 2022-03-01 (Expected Date: 2022-02-01)
10. Performing TEST with dates as 2022-10-28 and 2022-10-29 scenario
Testing condition : "-8 month" as parameter
- If PHP statement : Date('Y-m-01', strtotime("-8 month",
strtotime(Date("2022-10-28"))))
Value returned is 2022-02-01
- If PHP statement : Date('Y-m-01', strtotime("-8 month",
strtotime(Date("2022-10-29"))))
Incorrect Date Value returned is 2022-03-01 (Expected Date: 2022-02-01)
11. Performing TEST with dates as 2022-11-28 and 2022-11-29 scenario
Testing condition : "-9 month" as parameter
- If PHP statement : Date('Y-m-01', strtotime("-9 month",
strtotime(Date("2022-11-28"))))
Value returned is 2022-02-01
- If PHP statement : Date('Y-m-01', strtotime("-9 month",
strtotime(Date("2022-11-29"))))
Incorrect Date Value returned is 2022-03-01 (Expected Date: 2022-02-01)
12. Performing TEST with dates as 2022-12-28 and 2022-12-29 scenario
Testing condition : "-10 month" as parameter
- If PHP statement : Date('Y-m-01', strtotime("-10 month",
strtotime(Date("2022-12-28"))))
Value returned is 2022-02-01
- If PHP statement : Date('Y-m-01', strtotime("-10 month",
strtotime(Date("2022-12-29"))))
Incorrect Date Value returned is 2022-03-01 (Expected Date: 2022-02-01)
========= Testing for YEAR = 2024 , which is a Leap Year ========
1. Performing TEST with dates as 2024-01-28 and 2024-01-29 scenario
Testing condition : "-11 month" as parameter
- If PHP statement : Date('Y-m-01', strtotime("-11 month",
strtotime(Date("2024-01-28"))))
Value returned is 2023-02-01
- If PHP statement : Date('Y-m-01', strtotime("-11 month",
strtotime(Date("2024-01-29"))))
Incorrect Date Value returned is 2023-03-01 (Expected Date: 2023-02-01)
2. Performing TEST with dates as 2024-02-28 and 2024-02-29 scenario
Testing condition : "-12 month" as parameter
- If PHP statement : Date('Y-m-01', strtotime("-12 month",
strtotime(Date("2024-02-28"))))
Value returned is 2023-02-01
- If PHP statement : Date('Y-m-01', strtotime("-12 month",
strtotime(Date("2024-02-29"))))
Incorrect Date Value returned is 2023-03-01 (Expected Date: 2023-02-01)
3. Performing TEST with dates as 2024-03-28 and 2024-03-29 scenario
4. Performing TEST with dates as 2024-04-28 and 2024-04-29 scenario
5. Performing TEST with dates as 2024-05-28 and 2024-05-29 scenario
6. Performing TEST with dates as 2024-06-28 and 2024-06-29 scenario
7. Performing TEST with dates as 2024-07-28 and 2024-07-29 scenario
8. Performing TEST with dates as 2024-08-28 and 2024-08-29 scenario
9. Performing TEST with dates as 2024-09-28 and 2024-09-29 scenario
10. Performing TEST with dates as 2024-10-28 and 2024-10-29 scenario
11. Performing TEST with dates as 2024-11-28 and 2024-11-29 scenario
12. Performing TEST with dates as 2024-12-28 and 2024-12-29 scenario
```
But I expected this output instead:
```
For e.g., For year and month (2022 and Mar)
Date('Y-m-01', strtotime("-1 month",
strtotime(Date("2022-03-28")))) should return '2022-02-01'
Date('Y-m-01', strtotime("-1 month",
strtotime(Date("2022-03-29")))) should return '2022-02-01'
Additionally, the behaviour needs to work for both leap and non-leap years
```
### PHP Version
PHP 8.1.3
### Operating System
_No response_