Getting first weekday in a month with strtotime
Asked Answered
C

6

11

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 to fall on the 1st.

For a more general illustration of this problem, see the following code and result:

$mon = strtotime("December 2010 first monday");
$tue = strtotime("December 2010 first tuesday");
$wed = strtotime("December 2010 first wednesday");
$thu = strtotime("December 2010 first thursday");
$fri = strtotime("December 2010 first friday");
$sat = strtotime("December 2010 first saturday");
$sun = strtotime("December 2010 first sunday");

echo strftime("%m/%d/%y", $mon) . "<br>";
echo strftime("%m/%d/%y", $tue) . "<br>";
echo strftime("%m/%d/%y", $wed) . "<br>";
echo strftime("%m/%d/%y", $thu) . "<br>";
echo strftime("%m/%d/%y", $fri) . "<br>";
echo strftime("%m/%d/%y", $sat) . "<br>";
echo strftime("%m/%d/%y", $sun) . "<br>";

Results in:

12/06/10
12/07/10
12/08/10
12/02/10
12/03/10
12/04/10
12/05/10

Notice something? Shouldn't one day of the week coincide with the 1st of the month? But it never does, and instead the second instance of the day, on the 8th, is always returned.

Anyone have an explanation for this?

Cyrene answered 5/12, 2010 at 5:15 Comment(0)
M
8

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
Misogyny answered 5/12, 2010 at 5:37 Comment(2)
Well you could look at php source code if you <i>are</i> really curious, as for me, let's move on :DMisogyny
It doesn't seem to work entirely. I'm utilizing this solution on June 12th and I get 12/15/2014. Perhaps it's relative to the week of the month it currently is?Undershrub
C
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.

Cyrene answered 7/12, 2010 at 17:40 Comment(0)
M
8

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
Misogyny answered 5/12, 2010 at 5:37 Comment(2)
Well you could look at php source code if you <i>are</i> really curious, as for me, let's move on :DMisogyny
It doesn't seem to work entirely. I'm utilizing this solution on June 12th and I get 12/15/2014. Perhaps it's relative to the week of the month it currently is?Undershrub
A
5

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.

  1. It sets the day-of-month to 1.
  2. "ordinal dayname 'of' " does not advance to another day. (Example: "first tuesday of july 2008" means "2008-07-01").
  3. "ordinal dayname " does advance to another day. (Example: "first tuesday july 2008" means "2008-07-08", see also point 4 in the list above).
  4. "'last' dayname 'of' " takes the last dayname of the current month. (Example: "last wed of july 2008" means "2008-07-30")
  5. "'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").
Amerigo answered 5/12, 2010 at 8:55 Comment(2)
the 'of' format only works on PHP >=5.3, and fails on 5.2. See my answer for test results.Cyrene
@Yarin: Well spotted. Date handling in >=5.3 appears to be much more reliable than earlier versions. It's a shame there are so many potential pitfalls.Amerigo
D
1

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

Dorsal answered 8/3, 2011 at 4:4 Comment(0)
E
0

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.

Epergne answered 25/8, 2016 at 19:31 Comment(0)
I
0

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.

Indochina answered 13/12, 2019 at 18:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.