php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #63740 strtotime seems to use both sunday and monday as start of week
Submitted: 2012-12-11 15:18 UTC Modified: 2016-05-18 11:21 UTC
Votes:92
Avg. Score:4.6 ± 0.7
Reproduced:86 of 89 (96.6%)
Same Version:29 (33.7%)
Same OS:23 (26.7%)
From: salmanarshad2000 at yahoo dot com Assigned: derick
Status: Closed Package: Date/time related
PHP Version: 5.4.9 OS:
Private report: No CVE-ID:
 [2012-12-11 15:18 UTC] salmanarshad2000 at yahoo dot com
Description:
------------
Weeks start on Sunday or Monday. However, in this regard:

1) strtotime behavior is not documented.
2) strtotime produces inconsistent results when "this week" is used.

Sample dates from month of December 2012 used the the test script:

Mon 2012-12-03
Tue 2012-12-04
Wed 2012-12-05
Thu 2012-12-06
Fri 2012-12-07
Sat 2012-12-08
Sun 2012-12-09
Mon 2012-12-10
Tue 2012-12-11
Wed 2012-12-12
Thu 2012-12-13
Fri 2012-12-14
Sat 2012-12-15
Sun 2012-12-16


Test script:
---------------
// function strtotime called on Sun 2012-12-09
echo date("D Y-m-d", strtotime("monday this week", strtotime("2012-12-09"))); // Mon 2012-12-10
echo date("D Y-m-d", strtotime("sunday this week", strtotime("2012-12-09"))); // Sun 2012-12-16

// function strtotime called on Mon 2012-12-10
echo date("D Y-m-d", strtotime("monday this week", strtotime("2012-12-10"))); // Mon 2012-12-10
echo date("D Y-m-d", strtotime("sunday this week", strtotime("2012-12-10"))); // Sun 2012-12-16


Expected result:
----------------
If Sunday is start of the week then "sunday this week" be less than "monday this week":

// function strtotime called on Sun 2012-12-09
echo date("D Y-m-d", strtotime("monday this week", strtotime("2012-12-09"))); // Mon 2012-12-10
echo date("D Y-m-d", strtotime("sunday this week", strtotime("2012-12-09"))); // Sun 2012-12-09

// function strtotime called on Mon 2012-12-10
echo date("D Y-m-d", strtotime("monday this week", strtotime("2012-12-10"))); // Mon 2012-12-10
echo date("D Y-m-d", strtotime("sunday this week", strtotime("2012-12-10"))); // Sun 2012-12-09

If Monday is start of the week then "monday this week" should return different values on sunday and monday:

// function strtotime called on Sun 2012-12-09
echo date("D Y-m-d", strtotime("monday this week", strtotime("2012-12-09"))); // Mon 2012-12-03
echo date("D Y-m-d", strtotime("sunday this week", strtotime("2012-12-09"))); // Sun 2012-12-09

// function strtotime called on Mon 2012-12-10
echo date("D Y-m-d", strtotime("monday this week", strtotime("2012-12-10"))); // Mon 2012-12-10
echo date("D Y-m-d", strtotime("sunday this week", strtotime("2012-12-10"))); // Sun 2012-12-16

Actual result:
--------------
See test script, actual result is present alongside each line.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2013-01-23 16:04 UTC] googleguy@php.net
I've actually recently updated the documentation about strtotime in regard to this very 
behavior. See Bug #52143.

The problem is that prior to PHP 5.3.0 the relative time formats "this week", "next week", 
"previous week" were taken to mean a 7 day period relative to the current time. However, 
the behavior was changed in PHP 5.3.0 to be interpreted as "a week period of Monday 
through Sunday". This is noted in the documentation for strtotime in the changelog section 
since last week.

http://php.net/manual/en/function.strtotime.php#refsect1-function.strtotime-changelog

We can see this behavior more clearly from the following code...


var_dump(date("D Y-m-d", strtotime("this week", strtotime("2012-12-08"))));
string(14) "Mon 2012-12-03"

var_dump(date("D Y-m-d", strtotime("this week", strtotime("2012-12-09"))));
string(14) "Mon 2012-12-10"


Here what you'll notice is that "this week" always starts on a Monday. Now, when you want 
make that format relative to a particular day of the week, let's say Sunday...

var_dump(date("D Y-m-d", strtotime("Sunday this week", strtotime("2012-12-08"))));
string(14) "Sun 2012-12-09"

var_dump(date("D Y-m-d", strtotime("Sunday this week", strtotime("2012-12-09"))));
string(14) "Sun 2012-12-16"


What you should notice is that "this week" is first normalized to "Mon 2012-12-03" and 
"Mon 2012-12-10", respectively. Then the day is moved up to the first "Sunday" of that 
week (i.e. +6 days on each week).

This might sounds a little confusing because if you are expecting the week to begin on a 
Sunday and end on a Saturday then you would assume that "Sunday this week" would mean 
"2012-12-09" where the date is "2012-12-09" and the day is a Sunday. But that's not the 
case. "this week" means Monday of the current week and then move up until the very next 
Sunday. So if today is Sunday, we don't get today's date when we try "Sunday this week".
 [2013-01-24 08:31 UTC] salmanarshad2000 at yahoo dot com
The latter part which explains that "Sunday this week" is evaluated as (i) this week (ii) very next sunday is well explained and understandable. 

The former part which mentions that "time argument of strtotime() such as this week [is interpreted as] a week period of Monday through Sunday" is still 
confusing. It does return a Monday but does it return the correct Monday?

/* when today is  */                                                                        /* this week is   */
/* Mon 2012-12-03 */ echo date("D Y-m-d", strtotime("this week", strtotime("2012-12-03"))); /* Mon 2012-12-03 */
/* Tue 2012-12-04 */ echo date("D Y-m-d", strtotime("this week", strtotime("2012-12-04"))); /* Mon 2012-12-03 */
/* Wed 2012-12-05 */ echo date("D Y-m-d", strtotime("this week", strtotime("2012-12-05"))); /* Mon 2012-12-03 */
/* Thu 2012-12-06 */ echo date("D Y-m-d", strtotime("this week", strtotime("2012-12-06"))); /* Mon 2012-12-03 */
/* Fri 2012-12-07 */ echo date("D Y-m-d", strtotime("this week", strtotime("2012-12-07"))); /* Mon 2012-12-03 */
/* Sat 2012-12-08 */ echo date("D Y-m-d", strtotime("this week", strtotime("2012-12-08"))); /* Mon 2012-12-03 */
/* Sun 2012-12-09 */ echo date("D Y-m-d", strtotime("this week", strtotime("2012-12-09"))); /* Mon 2012-12-10 */

/* Mon 2012-12-10 */ echo date("D Y-m-d", strtotime("this week", strtotime("2012-12-10"))); /* Mon 2012-12-10 */
/* Tue 2012-12-11 */ echo date("D Y-m-d", strtotime("this week", strtotime("2012-12-11"))); /* Mon 2012-12-10 */
/* Wed 2012-12-12 */ echo date("D Y-m-d", strtotime("this week", strtotime("2012-12-12"))); /* Mon 2012-12-10 */
/* Thu 2012-12-13 */ echo date("D Y-m-d", strtotime("this week", strtotime("2012-12-13"))); /* Mon 2012-12-10 */
/* Fri 2012-12-14 */ echo date("D Y-m-d", strtotime("this week", strtotime("2012-12-14"))); /* Mon 2012-12-10 */
/* Sat 2012-12-15 */ echo date("D Y-m-d", strtotime("this week", strtotime("2012-12-15"))); /* Mon 2012-12-10 */
/* Sun 2012-12-16 */ echo date("D Y-m-d", strtotime("this week", strtotime("2012-12-16"))); /* Mon 2012-12-17 */

You can see that the output changes on Sundays, not Mondays. Expected:

"this week" on Sun 2012-12-09 should return the week starting Mon 2012-12-03 (ending on Sun 2012-12-09 inclusive)
"this week" on Sun 2012-12-16 should return the week starting Mon 2012-12-10 (ending on Sun 2012-12-16 inclusive)

Actual:

this week on Sun 2012-12-09 returns the week starting _coming_ Mon 2012-12-10 
this week on Sun 2012-12-16 returns the week starting _coming_ Mon 2012-12-17
 [2014-10-27 09:14 UTC] ca at noyo dot dk
I agree with salmanarshad2000, something's wrong here.

googleguy@php.net explains how "this week" is normalized:

"Sat 2012-12-08" is normalized to "Mon 2012-12-03"
"Sun 2012-12-09" is normalized to "Mon 2012-12-10". 

This seems wrong, the two days are in the same week. They should both normalize to "Mon 2012-12-03".
 [2015-07-13 09:51 UTC] mrtreinis at gmail dot com
This is a rather horrible bug, bumping for pressure. 

Another test sample: 

(date)->modify('Monday this week')

2015-07-06: 2015-07-06 // Mo - Mo
2015-07-07: 2015-07-06 // Tu - Mo
2015-07-08: 2015-07-06 // We - Mo
2015-07-09: 2015-07-06 // Th - Mo
2015-07-10: 2015-07-06 // Fr - Mo
2015-07-11: 2015-07-06 // Sa - Mo
2015-07-12: 2015-07-13 // Su - Mo next week???!!!
 [2016-02-03 10:30 UTC] szeli dot zsolt at hotmail dot com
similar problem ... when get actual week first and last day.
first day is: strtotime('this week last monday')
last day is: strtotime('this week next sunday') is coming back to the next week on sunday, so have to strtotime('this week last monday + 6 days')
 [2016-05-17 22:34 UTC] mateusz dot m dot nowaczyk at gmail dot com
I spent hours of scratching my head and analyzing SQL queries because of this bug - some financial reports were incorrectly calculated due to this behavior. I eventually implemented some ugly workaround. Why isn't this fixed, after three years?
 [2016-05-18 08:51 UTC] derick@php.net
This is indeed a bug. It should do weeks from Monday to Sunday, and hence, in:

Sat 2015-07-04 00:00 → Mon 2015-06-29 00:00
Sun 2015-07-05 00:00 → Mon 2015-07-06 00:00
Mon 2015-07-06 00:00 → Mon 2015-07-06 00:00
Tue 2015-07-07 00:00 → Mon 2015-07-06 00:00
Wed 2015-07-08 00:00 → Mon 2015-07-06 00:00
Thu 2015-07-09 00:00 → Mon 2015-07-06 00:00
Fri 2015-07-10 00:00 → Mon 2015-07-06 00:00
Sat 2015-07-11 00:00 → Mon 2015-07-06 00:00
Sun 2015-07-12 00:00 → Mon 2015-07-13 00:00
Mon 2015-07-13 00:00 → Mon 2015-07-13 00:00
Tue 2015-07-14 00:00 → Mon 2015-07-13 00:00

The following are wrong:

Sun 2015-07-05 00:00 → Mon 2015-07-06 00:00
Sun 2015-07-12 00:00 → Mon 2015-07-13 00:00

I'll investigate.
 [2016-05-18 11:20 UTC] derick@php.net
Automatic comment on behalf of github@derickrethans.nl
Revision: http://git.php.net/?p=php-src.git;a=commit;h=f43f6fc39b92796aa934d4ae13675bb144d23435
Log: Fixed bug #63740 (strtotime seems to use both sunday and monday as start of week)
 [2016-05-18 11:20 UTC] derick@php.net
-Status: Open +Status: Closed
 [2016-05-18 11:21 UTC] derick@php.net
-Assigned To: +Assigned To: derick
 [2016-05-18 11:21 UTC] derick@php.net
The fix for this bug has been committed.

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/.

 For Windows:

http://windows.php.net/snapshots/
 
Thank you for the report, and for helping us make PHP better.

Fixed for PHP 5.6.22, PHP 7.0.7 and PHP 7.1-dev
 [2016-09-11 09:47 UTC] sylvain at serval-agency dot fr
Hello,

I'm surprised the behavior of strtotime.

Today Sunday, September 11, 2016:
date ( 'd.m.Y', strtotime ('Saturday this week')); // 05.09.2016 instead of 09.10.2016
date ( 'd.m.Y', strtotime ('Friday this week')); // 05.09.2016 instead of 09.09.2016
 [2017-02-07 16:00 UTC] tony at brix dot ninja
the fix to this bug seems to have created a new bug

https://bugs.php.net/bug.php?id=74057
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Fri Feb 24 06:01:39 2017 UTC