Frequently PHP programmers get confused of the use of i month, -1 month, next month in strtotime() function. and hence it leaves some impression to programmer that this function is not that reliable.
Let's take one example of strtotime call with -1 month and see why it leaves this impression.
date("Y-m-d",strtotime("-1 month")) // Assume today is 2018-07-31
What's the output of above call? The answer is 2018-07-01. Why not 2018-06-30? So people get confused. It appears that this is wrong at first glance, but if think again, this output is reasonable.
Below is how the logic works
- It first minus one month, so the date becomes 2017-06-31
- Since June does not have 31 days, hence it will be canonicalized and becomes 2018-01-01. This is similar to why 2:60 will be 3:00
Now you get the point. This logic can also be verified with below call.
var_dump(date("Y-m-d", strtotime("2018-06-31")));
The output will be 2018-07-01. This behavior also applies to other months which have different days. Below are some more examples:
var_dump(date("Y-m-d", strtotime("-1 month", strtotime("2018-03-31")))); // Output 2018-03-03 var_dump(date("Y-m-d", strtotime("+1 month", strtotime("2018-08-31")))); // Output 2018-10-01 var_dump(date("Y-m-d", strtotime("next month", strtotime("2018-01-31")))); // Output 2018-03-03 var_dump(date("Y-m-d", strtotime("last month", strtotime("2018-03-31")))); // Output 2018-03-03
So how to make it work as expected? Starting from PHP 5.3, strtotime() added a few new tokens which can be used to correct this. They are first day of and last day of.
var_dump(date("Y-m-d", strtotime("last day of -1 month", strtotime("2018-03-31")))); // Output 2018-02-28 var_dump(date("Y-m-d", strtotime("first day of +1 month", strtotime("2018-08-31")))); // Output 2018-09-01 var_dump(date("Y-m-d", strtotime("first day of next month", strtotime("2018-01-31")))); // Output 2018-02-01 var_dump(date("Y-m-d", strtotime("last day of last month", strtotime("2018-03-31")))); // Output 2018-02-28
What if people are still using old version of PHP? mktime() could be used to achieve similar result.
Hence don't get panic when see this kind of "unexpected" behavior in the future.
Reference: http://www.laruence.com/2018/07/31/3207.html