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.
strtotime() is a lot more powerful than you think!
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'))