Asked  8 Months ago    Answers:  5   Viewed   38 times

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:


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?



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"));'

$ php -r 'echo date("m/d/y", strtotime("December 2010 Thursday"));'

$ php -r 'echo date("m/d/y", strtotime("December 2010 Friday"));'

$ php -r 'echo date("m/d/y", strtotime("December 2010 Saturday"));'

$ php -r 'echo date("m/d/y", strtotime("December 2010 Sunday"));'

$ php -r 'echo date("m/d/y", strtotime("December 2010 Monday"));'

$ php -r 'echo date("m/d/y", strtotime("December 2010 Tuesday"));'
Wednesday, March 31, 2021
answered 8 Months ago

How can I make it return today's date in that case?


if (today == monday)
    return today;
    return strtotime(...);

Btw, this trick also could work:

strtotime('last monday', strtotime('tomorrow'));
Wednesday, March 31, 2021
answered 8 Months ago

Why don't you get first monday, and do a loop adding 7 days to it until it is next year?

$first = strtotime("first monday of $year[$j]");
$lastday = mktime(0, 0, 0, 12, 31, $year[$j]);

$day = $first;
do {
    echo date('M d, Y', $day);
    $day += 7 * 86400;

} while ($day < $lastday);
Wednesday, March 31, 2021
answered 8 Months ago

strtotime doesn't "output" anything, btw : it returns false in case of an error ; see the manual :

Return Values

Returns a timestamp on success, FALSE otherwise. Previous to PHP 5.1.0, this function would return -1 on failure.

What doesn't output anything is echo : false is considered as an empty string, and nothing get outputed.

strtotime's documentation also gives the valid range for dates :

Note: The valid range of a timestamp is typically from Fri, 13 Dec 1901 20:45:54 UTC to Tue, 19 Jan 2038 03:14:07 UTC. (These are the dates that correspond to the minimum and maximum values for a 32-bit signed integer.) Additionally, not all platforms support negative timestamps, therefore your date range may be limited to no earlier than the Unix epoch. This means that e.g. dates prior to Jan 1, 1970 will not work on Windows, some Linux distributions, and a few other operating systems. PHP 5.1.0 and newer versions overcome this limitation though.

'0000-00-00' is outside of this range, so it's not considered a valid date ; hence the false return value.

As a sidenote, to really know what's inside a variable, you can use var_dump.
As a bnus, used with Xdebug, it'll get you a nice-formated output ;-)

Wednesday, March 31, 2021
answered 8 Months ago

Some basic code:

$month = 12;
$weekdays = array();
$d = 1;

do {
    $mk = mktime(0, 0, 0, $month, $d, date("Y"));
    @$weekdays[date("w", $mk)]++;
} while (date("m", $mk) == $month);


Remove the @ if your PHP error warning doesn't show notices.

Sunday, July 4, 2021
answered 4 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :