Calculate the difference between two dates in PHP using PHP 5.3 OOP or 5.2 procedural

Previously we have talked about MySQL datetime arithmetic. It is useful if your MySQL server runs on the timezone you want. But in case MySQL timezone is different or you want to do some date time arithmetic in your web application without database, then you need to know the fundamentals of datetime calculations of PHP. So, in this tutorial we are going to explain how to do some basic arithmetic of date and time in PHP using some of the built in PHP APIs. We will cover php datetime calculation for both the procedural style (PHP 5.2) as well as OOP style (PHP 5.3). Personally I prefer using PHP 5.3 style as it far less complicated and doesn’t depend upon integer range. But in case your server doesn’t provide PHP 5.3 you may use the older style instead. After reading this tutorial you will be able to:

  • Create any custom date using PHP mktime arithmetic.
  • Calculate difference between any two dates.
  • Make the difference readable in nice format (with years, months, days, hours, minutes, seconds etc).
  • Use a fallback function to automatically work between PHP 5.2 and 5.3.

So let us start. But before we do, as usual:

Online Demo[download id=”15″ format=”1″]

#1: Creating some custom dates:

Before we want to calculate the difference, we might want to create some custom dates based on datetime arithmetic. For that we shall use the mktime and date. Get more information about this function here and here.

#1.1: Create tomorrow’s date:

$date = mktime(0, 0, 0, date('m'), date('d') + 1, date('Y'));
var_dump(date('H:i:s Y-m-d', $date));

#1.2: Create next month’s date:

$date = mktime(0, 0, 0, date('m') + 1, date('d'), date('Y'));
var_dump(date('H:i:s Y-m-d', $date));

#1.3: Food for thought:

Create a date 2 days 6 months 10 years 12 hours 13 mins and 14 seconds from now:

[learn_more caption=”Check answer”]

$date = mktime(date('H') + 12, date('i') + 13, date('s') + 14, date('m') + 6, date('d') + 2, date('Y') + 10);
var_dump(date('H:i:s Y-m-d', $date));
//output string '05:50:24 2022-12-13' (length=19)

[/learn_more]

#2: Difference between two dates in second:

To calculate the difference between two dates we follow these strategies:

  • Convert the dates to UNIX timestamps using strtotime function. Read about it here.
  • Take the absolute of the arithmetic difference of the timestamps. This gives the time in second.

And example is given below:

/**
 * Calculate the difference between two dates
 */
$date_one = date('Y-m-d H:i:s');
$date_two = date('Y-m-d H:i:s', mktime(0, 0, 0, date('m'), date('d') + 1, date('Y')));

//get the difference in second
$dif = abs(strtotime($date_two) - strtotime($date_one));

#3: Make the difference human readable:

Now we shall make the difference in second easily readable by human. We shall convert the seconds into corresponding years, months, days, hours, minutes and seconds. To do that we shall use a converting function which is written below:

/**
 * Convert seconds to human readable format
 * in Year, Month, Day, Hour, Minute and Second
 * @param int $sec The second value
 * @return array The human readable format in an associative array
 */
function itg_sec_to_h($sec) {
    //make the $sec unsigned
    $sec = intval(abs($sec));
    //initialize the return array
    $ret = array(
        'year'      => 0,
        'month'     => 0,
        'day'       => 0,
        'hour'      => 0,
        'minute'    => 0,
        'second'    => 0,
    );

    //check if given second is zero
    if(0 == $sec)
        return $ret;

    //initialize the unit array
    $units = array(
        'year'      => 365*24*60*60,
        'month'     => 30*24*60*60,
        'day'       => 24*60*60,
        'hour'      => 60*60,
        'minute'    => 60,
        'second'    => 1,
    );

    //calculate the year, month, day, hour, minute, second
    foreach($units as $unit => $val) {
        $value = floor($sec/$val);
        $ret[$unit] = $value;
        $sec -= $value*$val;
    }

    return $ret;
}

Now we simply call it like:

//get the difference in human readable for PHP version < 5.3
$h_dif = itg_sec_to_h($dif);

//dump the variable
var_dump($h_dif);

and it gives output

array
  'year' => float 0
  'month' => float 0
  'day' => float 0
  'hour' => float 6
  'minute' => float 39
  'second' => float 39

The function returns the result in form of array. This is very useful as you can get the difference from the corresponding keys. Now try to solve the task below.

#3.1: Food for thought:

Write a function to calculate the weeks as well.

[learn_more caption=”Check answer”]

function itg_sec_to_h_week($sec) {
    //make the $sec unsigned
    $sec = intval(abs($sec));
    //initialize the return array
    $ret = array(
        'year'      => 0,
        'month'     => 0,
        'week'      => 0,
        'day'       => 0,
        'hour'      => 0,
        'minute'    => 0,
        'second'    => 0,
    );

    //check if given second is zero
    if(0 == $sec)
        return $ret;

    //initialize the unit array
    $units = array(
        'year'      => 365*24*60*60,
        'month'     => 30*24*60*60,
        'week'      => 7*24*60*60,
        'day'       => 24*60*60,
        'hour'      => 60*60,
        'minute'    => 60,
        'second'    => 1,
    );

    //calculate the year, month, day, hour, minute, second
    foreach($units as $unit => $val) {
        $value = floor($sec/$val);
        $ret[$unit] = $value;
        $sec -= $value*$val;
    }

    return $ret;
}

[/learn_more]

#4: Using PHP 5.3 OOP:

All these results can be easily achieved by using PHP 5.3 DateTime class. It gives several shortcuts to widely used datetime arithmetic. Read more about it here. The basics of the class is:

  • Create a DateTime object by passing a String date.
  • Call the diff method of an object and pass in the other DateTime object from which difference is to be calculated. Store the result in a variable.
  • The output variable holds the information of the date time difference in several member variable. It is basically a DateInterval objectwhich holds the information as follows:
    • y – The difference of years
    • m – The difference of months
    • d – The difference of days
    • h – The difference of hours
    • i – The difference of minutes
    • s – The difference of seconds
    • days – The total difference of days
  • We manipulate the output variable to get what we need.

An example of usage of DateTime is given below:

//get the difference using PHP 5.3 OOP method
$d_one = new DateTime($date_one);
$d_two = new DateTime($date_two);

//get the difference object
$d_diff = $d_one->diff($d_two);

//dump it
var_dump($d_diff);

//use the format string
var_dump($d_diff->format('%H hour %i minute %s second %d day %m month %Y year'));

This would output something like this:

object(DateInterval)[3]
  public 'y' => int 0
  public 'm' => int 0
  public 'd' => int 0
  public 'h' => int 6
  public 'i' => int 39
  public 's' => int 39
  public 'invert' => int 0
  public 'days' => int 0

string '06 hour 39 minute 39 second 0 day 0 month 00 year' (length=49)

#4.1: Food for thought:

Calculate the number of days between two dates.

[learn_more caption=”Check answer”]

$d1 = new DateTime('2012-06-01');
$d2 = new DateTime('2013-08-01');
$d3 = $d1->diff($d2);
var_dump($d3->days);
//outputs int 426

[/learn_more]

#5: Making a compatible function for 5.2 and 5.3:

Now let us put together a code and make something which will work for 5.3 OOP method and will fallback to normal floor method for 5.2.

/**
 * Calculate the difference between two dates
 * Prefers the PHP 5.3 DateTime OOP
 * If PHP version is less than 5.3 it uses procedural method instead
 * @param string $date_one The first date in H:i:s Y-m-d format
 * @param string $date_two The second date in H:i:s Y-m-d format
 * @return array the array containing year, month, day, hour, minute and second information. Access it like $arr['year'] etc.
 */
function itg_cal_difference_date($date_one, $date_two) {
    if(version_compare('5.3', phpversion(), '<=')) {
        $d_one = new DateTime($date_one);
        $d_two = new DateTime($date_two);
        $d_diff = $d_one->diff($d_two);
        return array(
            'year' => $d_diff->y,
            'month' => $d_diff->m,
            'day' => $d_diff->d,
            'hour' => $d_diff->h,
            'minute' => $d_diff->i,
            'second' => $d_diff->s,
        );
    } else {
        $d_one = strtotime($date_one);
        $d_two = strtotime($date_two);

        $sec = $d_one - $d_two;

        //make the $sec unsigned
        $sec = intval(abs($sec));
        //initialize the return array
        $ret = array(
            'year'      => 0,
            'month'     => 0,
            'day'       => 0,
            'hour'      => 0,
            'minute'    => 0,
            'second'    => 0,
        );

        //check if given second is zero
        if(0 == $sec)
            return $ret;

        //initialize the unit array
        $units = array(
            'year'      => 365*24*60*60,
            'month'     => 30*24*60*60,
            'day'       => 24*60*60,
            'hour'      => 60*60,
            'minute'    => 60,
            'second'    => 1,
        );

        //calculate the year, month, day, hour, minute, second
        foreach($units as $unit => $val) {
            $value = floor($sec/$val);
            $ret[$unit] = $value;
            $sec -= $value*$val;
        }

        return $ret;

    }
}

We call it like

$comp_f_call = itg_cal_difference_date($date_one, $date_two);
var_dump($comp_f_call);

and it returns an array as the output.

array
  'year' => int 0
  'month' => int 0
  'day' => int 0
  'hour' => int 6
  'minute' => int 30
  'second' => int 47

Use it wherever you like. So once again:

Online Demo[download id=”15″ format=”1″]

Hope this tutorial was useful for you. If you have any doubt or know something better don’t forget to drop in your comments.

3 comments

  1. Pingback: Howto: Calculate the remaining time of the day in PHP

Comments are closed.