Bookmark and Share

Comparing 2 dates in PHP – A better way

Posted: Saturday, July 11th, 2009 at 8:47 amUpdated: Monday, February 13th, 2012 at 11:02 am

If you Google around for php compare 2 dates, (at the time of this writing) typically they suggest for you to convert the date string into some integer using mktime() or strtotime(). Both the functions returns you Unix timestamp.

Understanding Unix Timestamp

In my other article, Getting around MySQL TIMEDIFF() for hours greater than 838, I mentioned that one of the golden rule of programming is to know about the function you are calling. This time, let’s find out more about those two functions by inspecting and understanding the return value.

From unixtimestamp.com, Unix timestamp is :


a way to track time as a running total of seconds. This count starts at the Unix Epoch on January 1st, 1970. Therefore, the unix time stamp is merely the number of seconds between a particular date and the Unix Epoch.

Problems with Unix Timestamp

The very definition of Unix timestamp should immediately raise awareness of possible limitation of implementing date comparison using mktime(), strtotime() or any other PHP functions that returns Unix timestamp. Below is the list of limitations.

  1. The definition says about counting the seconds passed after Unix Epoch. So obviously, the first problem is Unix timestamp can’t represent dates before January 1, 1970.
  2. Every variables in any programming language has size. An integer’s size is typically 32-bit. Without going into too much details, an integer can represent 24855 days, 3 hours, 14 minutes and 7 seconds. That means, Unixtime will rollover after January 19, 2038 at 03:14:07 AM.

To summarize, using Unix timestamp to compare 2 dates means you can only compare dates between January 1, 1970 to January 19, 2038.

Advantage of Unix Timestamp

It is only fair to say that there are some good in using Unix timestamp, especially if you’re using PHP’s mktime() or strtotime() functions. Since Unix timestamp counts number of seconds passed since Unix Epoch time, technically these two dates are equal: Jan 32, 2009 and Feb 1, 2009. If you convert those 2 dates to Unix timestamp, you will get the same number.

A better way to compare 2 dates in PHP

Now that we know more about Unix timestamp, here’s my proposal on what I think is a better way to compare dates in PHP. It is as simple as:


Just construct string of YYYYMMDD or for 24-hour format hour, construct string of YYYYMMDDHHMMSS. Then simply compare them.

The idea is that if you construct the date in 4 digit year followed by 2 digit month and 2 digit day, you’ll always counting forward. For example, 200900701 is greater than 20090702. It works on different months as well. For example, 20090815 is also greater. Similarly, it works on the year level as well.

If you have time in addition to dates, construct it so that the 2 digit hour is in 24-hour format. You’ll also see that HHMMSS will always greater for later time than earlier time.

Now that I hope you understand the concept, let’s dive into my little PHP function to compare 2 dates. I’m mostly working with date format MM/DD/YYYY so that’s what I’ll use. If this is not your date format, adjust as necessary.

function compare_dates($date1, $date2) {
	list($month, $day, $year) = preg_split(’/\//’, $date1);
	$new_date1 = sprintf('%04d%02d%02d', $year, $month, $day);
	
	list($month, $day, $year) = preg_split(’/\//’, $date2);
	$new_date2 = sprintf('%04d%02d%02d', $year, $month, $day);
	
	return ($new_date1 > $new_date2);
}

Problems with the better way to compare 2 dates

Most programming solutions have some kind of limitations. This particular one is no exception. Some may not say that the list below as problems, but I see it as limitation. Here are some:

  1. You loose the “flexibility” of using mktime() when comparing Jan 33, 2009 and Feb 1, 2009. In theory, Jan 33, 2009 equates to Feb 2, 2009. However, since the way we compare is to put month before day, any days in Feb (month 02) will trump over any days in Jan (month 01).
  2. Although the above code will work for any dates (even ones before Jan 1, 1000), it can’t compare dates greater than year 9999. One can simply change to 5-digit year (use %05d instead), but then you still have problems calculating year greater than 99999. It’s a never-ending limitation.

That’s it … It’s a long article about a simple thing as comparing dates, but I feel like it’s a good discussion, especially for the younger programmers out there to dig deep and fully understand what you’re programming. I hope you enjoyed this article. Please leave comments / suggestions / questions if you have. I’m looking forward to improving my solution with your comments / suggestions / questions.

11 Responses to “Comparing 2 dates in PHP – A better way”

  1. Sujith Says:

    Useful post.
    I was Googling for a php way to compare 2 dates
    .

  2. Alex Says:

    When using this function make sure that the dates passed in are formatted to ‘m/d/Y’; as in date(‘m/d/Y’).

  3. Akintunde Says:

    Just what I needed, thanks man!

  4. Phil Says:

    Same here: I googled for comparing 2 dates. Good post. I\’m going to use the code now in my program. Happy programming everybody! :)

  5. Simon Says:

    An excellent, simple solution to an age-old (for me) problem. Far better than strtotime() comparisons.

    One note: split() is deprecated as of PHP 5.3.0 – use preg_split(‘/\//’, $date1) instead!

  6. Maresa Says:

    Thanks Simon. I’ve updated the article.

  7. Hung-Su Says:

    Just copy pasted the code, that fix Simon posted contains a curly quote ’, not a straight quote! ‘

    Otherwise looks good, I’ll test this in a moment!

  8. Edward Says:

    Which is greater? 2011-05-15 or 2012-05-05. Your code returns the first as the greater. Any clue?

  9. Maresa Says:

    @Edward: My code would return the later to be greater.

  10. JohnG Says:

    @Edward: nice sarcasm, but you should use slashes ‘/’ and not dashes ‘-’ to separate year/month/day.

  11. Matt Says:

    @JohnG: I don’t think that was sarcastic, I think he was just mistaken. And actually, the YYYYMMDD format should be used with dashes, especially if you are using the date with MySQL. Slashes are more common with the American local date format of MM/DD/YYYY, which I’m assuming is why Maresa uses them here.

Leave a Reply


4 × nine =