php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #49904 DateTime::modify('last day') returns last day of the month
Submitted: 2009-10-16 16:45 UTC Modified: 2010-03-07 14:57 UTC
Votes:1
Avg. Score:3.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:0 (0.0%)
From: kgrecki at gmail dot com Assigned: derick (profile)
Status: Closed Package: Date/time related
PHP Version: 5.3, 6 (2009-10-19) OS: *
Private report: No CVE-ID: None
 [2009-10-16 16:45 UTC] kgrecki at gmail dot com
Description:
------------
call to modify('last day') has different effect in PHP 5.3 than in 5.2
It used to return a previous day, now it seems to return last day of the month,
according to http://www.gnu.org/software/automake/manual/tar/General-date-syntax.html#SEC115 "last" means -1 so 5.2 seems to get it right


Reproduce code:
---------------
date_default_timezone_set('Europe/London');

$dt = new DateTime('today');
var_dump($dt->format('c'));
$dt->modify('last day');
var_dump($dt->format('c'));

$dt = new DateTime('01-04-2009');
var_dump($dt->format('c'));
$dt->modify('last day');
var_dump($dt->format('c'));


Expected result:
----------------
PHP 5.2.11 (cli) (built: Sep 18 2009 10:59:00) 
string(25) "2009-10-16T00:00:00+01:00"
string(25) "2009-10-15T00:00:00+01:00"
string(25) "2009-04-01T00:00:00+01:00"
string(25) "2009-03-31T00:00:00+01:00"


Actual result:
--------------
PHP 5.3.0 (cli) (built: Jul 21 2009 17:02:21) 
string(25) "2009-10-16T00:00:00+01:00"
string(25) "2009-10-31T00:00:00+00:00"
string(25) "2009-04-01T00:00:00+01:00"
string(25) "2009-04-30T00:00:00+01:00"


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-10-19 10:36 UTC] jani@php.net
Obvious regression.
 [2010-01-15 14:03 UTC] yoarvi at gmail dot com
The cause of the problem seems to be the optional 'of' in the regex specification for the relative date operators 'first day of' and 'last day of'.

After applying the following patch (and regenerating parse_date.c) 

$dt->modify('first day'); is handled by the "relativetext" code block in parse_date.re
and
$dt->modify('first day of'); is handled by the "firstdayof | lastdayof" code block in parse_date.re
 

Index: ext/date/lib/parse_date.re
===================================================================
--- ext/date/lib/parse_date.re	(revision 293574)
+++ ext/date/lib/parse_date.re	(working copy)
@@ -931,8 +931,8 @@
 isoweekday       = year4 "-"? "W" weekofyear "-"? [0-7];
 isoweek          = year4 "-"? "W" weekofyear;
 exif             = year4 ":" monthlz ":" daylz " " hour24lz ":" minutelz ":" secondlz;
-firstdayof       = 'first day' ' of'?;
-lastdayof        = 'last day' ' of'?;
+firstdayof       = 'first day of';
+lastdayof        = 'last day of'?;
 backof           = 'back of ' hour24 space? meridian?;
 frontof          = 'front of ' hour24 space? meridian?;
 [2010-01-15 20:05 UTC] derick@php.net
Good point, but there is a reason why I made that 'of' bit optional, I'll have to have a good look at why.
 [2010-01-19 12:28 UTC] yoarvi at gmail dot com
The following patch is a test case for this bug:

Index: ext/date/tests/bug49904.phpt
===================================================================
--- ext/date/tests/bug49904.phpt	(revision 0)
+++ ext/date/tests/bug49904.phpt	(revision 0)
@@ -0,0 +1,27 @@
+--TEST--
+Bug #49904 (DateTime::modify('last day') returns last day of the month)
+--FILE--
+<?php
+date_default_timezone_set('Asia/Calcutta');
+
+$dt = new DateTime('18-01-2010');
+var_dump($dt->format('c'));
+$dt->modify('last day');
+var_dump($dt->format('c'));
+$dt->modify('last day of');
+var_dump($dt->format('c'));
+
+$dt = new DateTime('18-01-2010');
+var_dump($dt->format('c'));
+$dt->modify('first day');
+var_dump($dt->format('c'));
+$dt->modify('first day of');
+var_dump($dt->format('c'));
+?>
+--EXPECT--
+string(25) "2010-01-18T00:00:00+05:30"
+string(25) "2010-01-17T00:00:00+05:30"
+string(25) "2010-01-31T00:00:00+05:30"
+string(25) "2010-01-18T00:00:00+05:30"
+string(25) "2010-01-19T00:00:00+05:30"
+string(25) "2010-01-01T00:00:00+05:30"
 [2010-03-07 14:57 UTC] derick@php.net
-Status: Assigned +Status: Closed
 [2010-03-07 14:57 UTC] derick@php.net
This bug has been fixed in SVN.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.

Duplicate of bug #51096 which is now fixed in SVN.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Mon Apr 28 09:01:27 2025 UTC