Let’s say we have the following problem: we have to check whether a date is more than a month ago or less than a month ago. Many developers go in the wrong direction by calculating the current month and then subtracting the number of months from it. Of course, this approach is slow and full of risks of allowing bugs. Since, two months before January, which is the first month of the year, is actually November, which is the eleventh month. Because of these pitfalls, this approach is entirely wrong.
The question is whether PHP cannot help us with built-in functions to perform these calculations for us. It is obvious, that from version 5.3.0 and later, there is an OOP section, which is great, but unfortunately this version is still not updated everywhere. So, how to accomplish the task?
The Wrong Approach
As I said, there are many ways to go in the wrong direction. One of them is to subtract 30 days from current date. This is completely wrong, because not every month has 30 days. Here, some developers will begin to predefine arrays to indicate the number of days in each month, which then will be used in their complicated calculations. Here is an example of this wrong approach.
echo date('Y-m-d', strtotime(date('Y-m-d')) - 60*60*24*30);
This line is full of mistakes. First of all strtotime(date(‘Y-m-d’)) can be replaced by the more elegant strtotime(‘now’), but for this later. Another big mistake is that 60*60*24*30, which is number of seconds in 30 days can be predefined as a constant. Eventually the result is wrong, because not every month has 30 days.
The Correct Approach
A small research of the problem and the functions in versions prior of 5.3.0 of PHP is needed. Typical case study of date formatting happen when working with dates from a database. The following code is a classical example.
// 2008 05 23, 2008-05-23 is stored into the DB echo date('Y m d', strtotime('2008-05-23')); // 2008 May 23 echo date('Y F d', strtotime('2008-05-23'));
The problem, perhaps, is that too often strtotime() is used like this, with exactly this type of strings. However much more interesting is that strtotime() can do much more.
strtotime() Can Do Much More
Let us first look at the documentation of this function. What parameters it accepts?
int strtotime ( string $time [, int $now = time() ] )
The function expects to be given a string containing an English date format and will try to parse that format into a Unix timestamp (the number of seconds since January 1 1970 00:00:00 UTC), relative to the timestamp given in now, or the current time if now is not supplied.
In particular we are interested in the first parameter, time.
time – A date/time string. Valid formats are explained in Date and Time Formats.
It is especially important to note what are the valid Date and Time Formats.
Here are the supported formats, but most interesting are those that are Relative.
Exactly these formats are very convenient in our case, because they give us the ability to work with human readable strings, and here are some examples from the documentation of strtotime().
echo strtotime("now"), "\n"; echo strtotime("10 September 2000"), "\n"; echo strtotime("+1 day"), "\n"; echo strtotime("+1 week"), "\n"; echo strtotime("+1 week 2 days 4 hours 2 seconds"), "\n"; echo strtotime("next Thursday"), "\n"; echo strtotime("last Monday"), "\n";
Thus, a valid string would be “1 month ago”.
// if current date is 2011-11-04, this will return 2011-10-04 echo date('Y-m-d', strtotime('1 month ago'))
Or “-1 month”:
// the same as the example above echo date('Y-m-d', strtotime('-1 month'));
It’s interesting that “+1 -1 month” is also a valid string.
// 2011-10-04, if today's 2011-11-04 echo date('Y-m-d', strtotime('+1 -1 month'));
In fact strtotime() can do a lot more than most of the developers have ever imagined. Maybe its frequent use with string formatted dates (2010-01-13) makes it a bit unknown. Here are some interesting use cases.
// 1970-01-01, Calculations in braces are bad! echo date('Y-m-d', strtotime('(60*60) minute')); // 2 months into the future echo date('Y-m-d', strtotime('-2 months ago'));
For instance, do you know how to get the date of the day before yesterday? Yes 2 days before today, but here’s yet another solution.
// 1 day before yesterday echo date('Y-m-d', strtotime('yesterday -1 day'));
Another example is the fully human readable:
// get the first monday of the current month echo date('Y-m-d', strtotime('first monday this month'));
The Solution of the Task
Finally, what is the solution of the original task? Well, just have to check whether a date is more or less than a month ago.
// a random date $my_date = '2011-09-23'; // true if my_date is more than a month ago (strtotime($my_date) < strtotime('1 month ago'))