php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #43452 strtotime returns wrong date when requested day is same as first day of the mon
Submitted: 2007-11-29 15:39 UTC Modified: 2009-05-11 03:20 UTC
Votes:5
Avg. Score:4.8 ± 0.4
Reproduced:4 of 4 (100.0%)
Same Version:1 (25.0%)
Same OS:0 (0.0%)
From: sean dot thorne at gmail dot com Assigned: derick
Status: Closed Package: Date/time related
PHP Version: 5.2CVS-2008-10-21 OS: *
Private report: No CVE-ID:
 [2007-11-29 15:39 UTC] sean dot thorne at gmail dot com
Description:
------------
When asking strtotime for the 3rd thursday in a month and the first day of that month is thursday, it ignores the first thursday. It then begins to count after that first Thursday and returns the fourth Thursday.

Reproduce code:
---------------
$day = strtotime("3 Thursday Nov 2007");
echo date("m-d-Y", $day);

Expected result:
----------------
11-15-2007

Actual result:
--------------
11-22-2007

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2008-04-02 14:06 UTC] billyt at claritytech dot com
We also wrote our own function that handles it. Although, it's purely by random chance that we discovered the problem. It's not something we would specifically have tested for.  I wonder how many other people are using it in production with no idea that it's a problem.
 [2008-06-17 17:21 UTC] soapergem at gmail dot com
I also confirmed this. This is pretty serious, too! There are an infinite number of examples in which you can reproduce it; here are a few:


  //  expect 06-15-2008, get 06-22-2008
  $date = strtotime('3 Sunday June 2008');
  echo date('m-d-Y', $date);
  
  //  expect 07-08-2008, get 07-15-2008
  $date = strtotime('2 Tuesday July 2008');
  echo date('m-d-Y', $date);
  
  //  expect 08-22-2008, get 08-29-2008
  $date = strtotime('4 Friday August 2008');
  echo date('m-d-Y', $date);
  
  //  expect 09-29-2008, get 10-06-2008
  $date = strtotime('5 Monday September 2008');
  echo date('m-d-Y', $date);
  
  //  expect 10-01-2008, get 10-08-2008
  $date = strtotime('1 Wednesday October 2008');
  echo date('m-d-Y', $date);


Developers please take note: THIS IS A SERIOUS BUG! (and it's been around for a long time)
 [2008-07-15 17:19 UTC] m dot ford at leedsmet dot ac dot uk
Derick, please take another look at this.

I've examined it in some depth, and tend to agree there's a bug here.  However, if you read the GNU Date Input Formats syntax, linked from http://php.net/manual/function.strtotime.php, very closely, you find it says:

"a day of the week will forward the date (only if necessary) to reach that day of the week in the future"

... and ...

"a number may precede a day of the week item to move forward supplementary weeks."

The crucial word here is "supplementary". Taken together, these specifications suggest that, somewhat counter-intuitively:

   Monday month year

should represent the first Monday of the month, no matter what date it falls on, and

   1 Monday month year

should be the Monday *after* that (i.e. the 2nd Monday!!), and so on. Other wording in the GNU Date "Day of week items" section would tend to confirm this interpretation.

I therefore submit that the bug actually manifests when the first occurrence of the requested weekday falls on any date *other* than the first of the month! :(

However you interpret it, it's nonetheless clear that the relationship of "1 weekday" to "weekday" should be fixed -- either according to the GNU specification to occur 1 week later, or more intuitively to mean the same thing. It's definitely NOT right that "1 Monday" (for example) means something different from "Monday" *only* when "Monday" is the 1st of the month...!!
 [2008-07-15 17:23 UTC] derick@php.net
Assigning this to myself, but be aware that we do not necessarily implement this GNU date stuff -- we've never done this either. I'll check it though.
 [2008-07-17 10:29 UTC] m dot ford at leedsmet dot ac dot uk

 [2008-07-17 10:32 UTC] derick@php.net
Yeah, and I've done some work on that -- but it's not ready yet.
 [2008-07-23 18:50 UTC] derick@php.net
This bug has been fixed in CVS.

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.


 [2008-10-16 16:29 UTC] till@php.net
Sorry to re-open, I found the same bug on:
PHP Version 5.2.6-pl6-gentoo

Some code to reproduce:
<?php
echo date('Y-m-d', strtotime('first Monday', mktime(0, 0, 0, 12, 1, 2008)));
?>

Shows 2008-12-08, while indeed the first Monday in December is 2008-12-01.


 [2008-10-16 22:56 UTC] till@php.net
I had second thoughts about the "timestamp" passed into strtotime(), so I tried to create the date in a slightly different way but it failed never the less.

I can also confirm this on 5.2.6_2 on FreeBSD.

Additional code:

Works:
<?php
// 2008-12-02
echo date('Y-m-d', strtotime('first Tuesday December 2008'));
?>

Does not:
<?php
// 2008-12-08
echo date('Y-m-d', strtotime('first Monday December 2008'));
?>
 [2008-10-16 23:18 UTC] till@php.net
Confirmed it broken in 5.2.7-dev as well.

Since it appears to be fixed in 5.3-alpha3-dev, is there any chance this fix can be backported?
 [2008-10-21 12:05 UTC] jani@php.net
Derick, feedback was given..
 [2008-11-02 13:17 UTC] jani@php.net
Derick, this bug has obviously been fixed in PHP_5_2. As it has been 
a bugfix why isn't it committed to PHP_5_2?!
 [2008-11-02 13:24 UTC] derick@php.net
This bug has been fixed in CVS.

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.

I merged this last weekend, so closing.
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Sat Apr 19 22:02:16 2014 UTC