I found something odd about strtotime().
On dates that do not exist it returns the day after.
$d30= strtotime("2017-06-30");
Echo $d30 ."\n";
Echo date("Y-m-d", $d30)."\n\n"; // 2017-06-30
$d31= strtotime("2017-06-31");
Echo $d31 ."\n";
Echo date("Y-m-d", $d31)."\n\n"; // 2017-07-01
$d32= strtotime("2017-06-32");
Echo $d32 ."\n";
Echo date("Y-m-d", $d32); // 1970-01-01
https://3v4l.org/AjMAE
I understand the last one. It returns nothing as it's an error.
But why does the second one return first of July?
Is it a meant to be functional, in case you make a mistake it will "correct you"? Or is it a true bug in strtotime()?
If you look at the docs for strtotime() you will see the first parameter is:
time
A date/time string. Valid formats are explained in Date and Time Formats.
If you follow the link for the date and time formats and go to Date Formats you will see:
Thus for the date format (I.e. DD), 01-31 is valid (since a 3 can only be followed by a 0 or 1) despite the month. Depending on the supplied month and date value the date will be adjusted.
Also found in the notes on that same page:
Note:
It is possible to over- and underflow the dd and DD format. Day 0 means the last day of previous month, whereas overflows count into the next month. This makes "2008-08-00" equivalent to "2008-07-31" and "2008-06-31" equivalent to "2008-07-01" (June only has 30 days).1
Hence 06-31 is valid while 06-32 is invalid.
Additionally, in the User Contributed Notes section, the note by Mirek at 2015-04-01 01:14 might be useful/interesting:
Note: the day (dd or DD) is first checked for range 0..31 and only if it fits, the overflow and underflow mechanism may apply. If not, strtotime() simply returns false.
If you need unlimited over/underflow for date calculations (for example 2015-01-40 to 2015-02-09), use mktime() instead.2
1http://php.net/manual/en/datetime.formats.date.php
2http://php.net/manual/en/datetime.formats.date.php#Hcom117014
As day 31
of a month is possible strtotime()
will correct the date for you. If you try it with February (2017-02-31) it will correct to 2017-03-03
. This is what you found.
So, what it essentially does is:
- get the date
- check if the date is in a valid range (days per
month)
- if not valid count days into the next month
This behaviour is implemented into the strtotime
function itself.
There was a great comment on the documentation page about this, but I am no longer able to find it. This comment provides some extra information (be sure to check the link in the comment).