php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #65412 strtotime('2013-07-31 -1 month') return wrong result
Submitted: 2013-08-07 09:19 UTC Modified: 2013-08-07 20:09 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: laurisnet at inbox dot lv Assigned:
Status: Not a bug Package: Date/time related
PHP Version: 5.4Git-2013-08-07 (Git) OS: Windows 7 64bit
Private report: No CVE-ID: None
 [2013-08-07 09:19 UTC] laurisnet at inbox dot lv
Description:
------------
Function strtotime() return wrong value for 2013-07-31 date with parameters:
A) -1 month
B) last month

Test script:
---------------
<?
// This returns: 2013-07-01
// But expected was: 2013-06-30
echo date("Y-m-d", strtotime('2013-07-31 -1 month'));
?>

Expected result:
----------------
2013-06-30

Actual result:
--------------
2013-07-01

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2013-08-07 20:09 UTC] rasmus@php.net
-Status: Open +Status: Not a bug
 [2013-08-07 20:09 UTC] rasmus@php.net
This is not a bug. This is standard behaviour for date arithmetic when the target 
date is impossible. There is an explanation from the GNU tools here:

http://www.gnu.org/software/tar/manual/html_chapter/Date-input-
formats.html#SEC125
 [2013-08-07 20:26 UTC] mail+php at requinix dot net
"-1 month" is literally subtracting one month from the date. 2013-07-31 becomes 
2013-06-31 which overflows to 2013-07-01. Likewise "2013-03-31 -1 month" becomes 
2013-03-03.

If you want the last day of the previous month then the method I know (using 
only strtotime) is going to the beginning of the month, subtracting a month, and 
going to the last day:

strtotime("2013-07-31, first day of, -1 month, last day of")
Keep an eye on http://php.net/datetime.formats.relative

But it's much easier with mktime(0, 0, 0, month, 0, year).
 [2013-08-08 05:54 UTC] laurisnet at inbox dot lv
I made fix for this, in case somesone has same situation:


$today_date = '2013-07-31'; 
$current_month = date("n", strtotime("$today_date"));
$prev_full_date = $today_date.' 23:59:59';
$prev_full_date = date("Y-m-d H:i:s", strtotime("$prev_full_date -1 month"));

// 2013-07-31 => 2013-07-01 => 2013-06-30
$prev_year = date("Y", strtotime("$today_date -1 month"));
$prev_month = date("m", strtotime("$today_date -1 month"));
$days_in_prev_month = date("t", strtotime("$today_date -1 month")); // Dienu 
skaits 
iepriekšējā mēnesi date(t)
if(date("n", strtotime($prev_full_date)) == $current_month){
	$prev_full_date = date("Y-m-d H:i:s", strtotime("$prev_full_date -1 
day"));
}
else{
	$prev_full_date_tmp = "$prev_year-$prev_month-$days_in_prev_month 
23:59:59";
	$prev_full_date = date("Y-m-d H:i:s", strtotime($prev_full_date_tmp));
}
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Sat May 03 14:01:30 2025 UTC