I\'m trying to figure out the first wednesday of a given month using strtotime
, but the \"first wednesday\" argument fails whenever the first wednesday happens
I believe it's the order in which you are placing values. When you write "December 2010", it already is going to 12/01/2010. When adding "first {day}", function goes for that very first day, after the 12/01/2010. I think if you declare the "first {day}" value and then "december 2010" it should work fine.
It's just your formatting that is incorrect. You need to include of
:
echo strftime("%m/%d/%y", strtotime("first Monday of December 2010"));
echo strftime("%m/%d/%y", strtotime("first Tuesday of December 2010"));
echo strftime("%m/%d/%y", strtotime("first Wednesday of December 2010"));
echo strftime("%m/%d/%y", strtotime("first Thursday of December 2010"));
echo strftime("%m/%d/%y", strtotime("first Friday of December 2010"));
echo strftime("%m/%d/%y", strtotime("first Saturday of December 2010"));
echo strftime("%m/%d/%y", strtotime("first Sunday of December 2010"));
Prints:
12/06/10
12/07/10
12/01/10
12/02/10
12/03/10
12/04/10
12/05/10
The accepted solution works, but you would encounter problems if you wanted to find the second weekday:
echo strftime("%m/%d/%y", strtotime("December 2010 second Wednesday"));
Prints:
12/15/10
There are some examples given in the docs:
http://www.php.net/manual/en/datetime.formats.relative.php
The second block of notes in the above documentation explains how of
affects the date calculation process:
Also observe that the "of" in "ordinal space dayname space 'of' " and "'last' space dayname space 'of' " does something special.
- It sets the day-of-month to 1.
- "ordinal dayname 'of' " does not advance to another day. (Example: "first tuesday of july 2008" means "2008-07-01").
- "ordinal dayname " does advance to another day. (Example: "first tuesday july 2008" means "2008-07-08", see also point 4 in the list above).
- "'last' dayname 'of' " takes the last dayname of the current month. (Example: "last wed of july 2008" means "2008-07-30")
- "'last' dayname" takes the last dayname from the current day. (Example: "last wed july 2008" means "2008-06-25"; "july 2008" first sets the current date to "2008-07-01" and then "last wed" moves to the previous Wednesday which is "2008-06-25").
I found this note in the PHP manual.
"In PHP 5 prior to 5.2.7, requesting a given occurrence of a given weekday in a month where that weekday was the first day of the month would incorrectly add one week to the returned timestamp. This has been corrected in 5.2.7 and later versions."
I don't have any explanation as I'm also dazzled, but I managed to find out how you get the correct date by omitting the "first", like so:
$ php -r 'echo date("m/d/y", strtotime("December 2010 Wednesday"));'
12/01/10
$ php -r 'echo date("m/d/y", strtotime("December 2010 Thursday"));'
12/02/10
$ php -r 'echo date("m/d/y", strtotime("December 2010 Friday"));'
12/03/10
$ php -r 'echo date("m/d/y", strtotime("December 2010 Saturday"));'
12/04/10
$ php -r 'echo date("m/d/y", strtotime("December 2010 Sunday"));'
12/05/10
$ php -r 'echo date("m/d/y", strtotime("December 2010 Monday"));'
12/06/10
$ php -r 'echo date("m/d/y", strtotime("December 2010 Tuesday"));'
12/07/10
Building off the answers provided, one needs to be aware of differences in relative date formatting between php 5.2 and php 5.3.
TEST:
$date1 = strtotime("first wednesday of 2010-12");
$date2 = strtotime("first wednesday 2010-12");
$date3 = strtotime("wednesday 2010-12");
5.2 Results:
1969-12-31
2010-12-08
2010-12-01
5.3 Results:
2010-12-01
2010-12-08
2010-12-01
Therefore only the third method returns correct results across PHP 5 versions.
PHP 5.5.11
$firstWeekdayOfMonth = new DateTime('first weekday 0 jun 2016');
I don't know why, but the zero kind of force the strtotime parser to start at the beginning of the month considering the first day.