How to calculate the difference between two dates using PHP?

PhpDatetimeDatediff

Php Problem Overview


I have two dates of the form:

Start Date: 2007-03-24 
End Date: 2009-06-26

Now I need to find the difference between these two in the following form:

2 years, 3 months and 2 days

How can I do this in PHP?

Php Solutions


Solution 1 - Php

I suggest to use DateTime and DateInterval objects.

$date1 = new DateTime("2007-03-24");
$date2 = new DateTime("2009-06-26");
$interval = $date1->diff($date2);
echo "difference " . $interval->y . " years, " . $interval->m." months, ".$interval->d." days "; 

// shows the total amount of days (not divided into years, months and days like above)
echo "difference " . $interval->days . " days ";

read more php DateTime::diff manual

From the manual: > As of PHP 5.2.2, DateTime objects can be compared using comparison operators.

$date1 = new DateTime("now");
$date2 = new DateTime("tomorrow");

var_dump($date1 == $date2); // bool(false)
var_dump($date1 < $date2);  // bool(true)
var_dump($date1 > $date2);  // bool(false)

Solution 2 - Php

> Use this for legacy code (PHP < 5.3). For up to date solution see jurka's answer below

You can use strtotime() to convert two dates to unix time and then calculate the number of seconds between them. From this it's rather easy to calculate different time periods.

$date1 = "2007-03-24";
$date2 = "2009-06-26";

$diff = abs(strtotime($date2) - strtotime($date1));

$years = floor($diff / (365*60*60*24));
$months = floor(($diff - $years * 365*60*60*24) / (30*60*60*24));
$days = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24)/ (60*60*24));

printf("%d years, %d months, %d days\n", $years, $months, $days);

Edit: Obviously the preferred way of doing this is like described by jurka below. My code is generally only recommended if you don't have PHP 5.3 or better.

Several people in the comments have pointed out that the code above is only an approximation. I still believe that for most purposes that's fine, since the usage of a range is more to provide a sense of how much time has passed or remains rather than to provide precision - if you want to do that, just output the date.

Despite all that, I've decided to address the complaints. If you truly need an exact range but haven't got access to PHP 5.3, use the code below (it should work in PHP 4 as well). This is a direct port of the code that PHP uses internally to calculate ranges, with the exception that it doesn't take daylight savings time into account. That means that it's off by an hour at most, but except for that it should be correct.

<?php

/**
 * Calculate differences between two dates with precise semantics. Based on PHPs DateTime::diff()
 * implementation by Derick Rethans. Ported to PHP by Emil H, 2011-05-02. No rights reserved.
 * 
 * See here for original code:
 * http://svn.php.net/viewvc/php/php-src/trunk/ext/date/lib/tm2unixtime.c?revision=302890&view=markup
 * http://svn.php.net/viewvc/php/php-src/trunk/ext/date/lib/interval.c?revision=298973&view=markup
 */

function _date_range_limit($start, $end, $adj, $a, $b, $result)
{
    if ($result[$a] < $start) {
        $result[$b] -= intval(($start - $result[$a] - 1) / $adj) + 1;
        $result[$a] += $adj * intval(($start - $result[$a] - 1) / $adj + 1);
    }

    if ($result[$a] >= $end) {
        $result[$b] += intval($result[$a] / $adj);
        $result[$a] -= $adj * intval($result[$a] / $adj);
    }

    return $result;
}

function _date_range_limit_days($base, $result)
{
    $days_in_month_leap = array(31, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
    $days_in_month = array(31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);

    _date_range_limit(1, 13, 12, "m", "y", &$base);

    $year = $base["y"];
    $month = $base["m"];

    if (!$result["invert"]) {
        while ($result["d"] < 0) {
            $month--;
            if ($month < 1) {
                $month += 12;
                $year--;
            }

            $leapyear = $year % 400 == 0 || ($year % 100 != 0 && $year % 4 == 0);
            $days = $leapyear ? $days_in_month_leap[$month] : $days_in_month[$month];

            $result["d"] += $days;
            $result["m"]--;
        }
    } else {
        while ($result["d"] < 0) {
            $leapyear = $year % 400 == 0 || ($year % 100 != 0 && $year % 4 == 0);
            $days = $leapyear ? $days_in_month_leap[$month] : $days_in_month[$month];

            $result["d"] += $days;
            $result["m"]--;

            $month++;
            if ($month > 12) {
                $month -= 12;
                $year++;
            }
        }
    }

    return $result;
}

function _date_normalize($base, $result)
{
    $result = _date_range_limit(0, 60, 60, "s", "i", $result);
    $result = _date_range_limit(0, 60, 60, "i", "h", $result);
    $result = _date_range_limit(0, 24, 24, "h", "d", $result);
    $result = _date_range_limit(0, 12, 12, "m", "y", $result);

    $result = _date_range_limit_days(&$base, &$result);

    $result = _date_range_limit(0, 12, 12, "m", "y", $result);

    return $result;
}

/**
 * Accepts two unix timestamps.
 */
function _date_diff($one, $two)
{
    $invert = false;
    if ($one > $two) {
        list($one, $two) = array($two, $one);
        $invert = true;
    }

    $key = array("y", "m", "d", "h", "i", "s");
    $a = array_combine($key, array_map("intval", explode(" ", date("Y m d H i s", $one))));
    $b = array_combine($key, array_map("intval", explode(" ", date("Y m d H i s", $two))));

    $result = array();
    $result["y"] = $b["y"] - $a["y"];
    $result["m"] = $b["m"] - $a["m"];
    $result["d"] = $b["d"] - $a["d"];
    $result["h"] = $b["h"] - $a["h"];
    $result["i"] = $b["i"] - $a["i"];
    $result["s"] = $b["s"] - $a["s"];
    $result["invert"] = $invert ? 1 : 0;
    $result["days"] = intval(abs(($one - $two)/86400));

    if ($invert) {
        _date_normalize(&$a, &$result);
    } else {
        _date_normalize(&$b, &$result);
    }

    return $result;
}

$date = "1986-11-10 19:37:22";

print_r(_date_diff(strtotime($date), time()));
print_r(_date_diff(time(), strtotime($date)));

Solution 3 - Php

The best course of action is using PHP's DateTime (and DateInterval) objects. Each date is encapsulated in a DateTime object, and then a difference between the two can be made:

$first_date = new DateTime("2012-11-30 17:03:30");
$second_date = new DateTime("2012-12-21 00:00:00");

The DateTime object will accept any format strtotime() would. If an even more specific date format is needed, DateTime::createFromFormat() can be used to create the DateTime object.

After both objects were instantiated, you substract one from the other with DateTime::diff().

$difference = $first_date->diff($second_date);

$difference now holds a DateInterval object with the difference information. A var_dump() looks like this:

object(DateInterval)
  public 'y' => int 0
  public 'm' => int 0
  public 'd' => int 20
  public 'h' => int 6
  public 'i' => int 56
  public 's' => int 30
  public 'invert' => int 0
  public 'days' => int 20

To format the DateInterval object, we'll need check each value and exclude it if it's 0:

/**
 * Format an interval to show all existing components.
 * If the interval doesn't have a time component (years, months, etc)
 * That component won't be displayed.
 *
 * @param DateInterval $interval The interval
 *
 * @return string Formatted interval string.
 */
function format_interval(DateInterval $interval) {
    $result = "";
    if ($interval->y) { $result .= $interval->format("%y years "); }
    if ($interval->m) { $result .= $interval->format("%m months "); }
    if ($interval->d) { $result .= $interval->format("%d days "); }
    if ($interval->h) { $result .= $interval->format("%h hours "); }
    if ($interval->i) { $result .= $interval->format("%i minutes "); }
    if ($interval->s) { $result .= $interval->format("%s seconds "); }

    return $result;
}

All that's left now is to call our function on the $difference DateInterval object:

echo format_interval($difference);

And we get the correct result:

> 20 days 6 hours 56 minutes 30 seconds

The complete code used to achieve the goal:

/**
 * Format an interval to show all existing components.
 * If the interval doesn't have a time component (years, months, etc)
 * That component won't be displayed.
 *
 * @param DateInterval $interval The interval
 *
 * @return string Formatted interval string.
 */
function format_interval(DateInterval $interval) {
    $result = "";
    if ($interval->y) { $result .= $interval->format("%y years "); }
    if ($interval->m) { $result .= $interval->format("%m months "); }
    if ($interval->d) { $result .= $interval->format("%d days "); }
    if ($interval->h) { $result .= $interval->format("%h hours "); }
    if ($interval->i) { $result .= $interval->format("%i minutes "); }
    if ($interval->s) { $result .= $interval->format("%s seconds "); }

    return $result;
}

$first_date = new DateTime("2012-11-30 17:03:30");
$second_date = new DateTime("2012-12-21 00:00:00");

$difference = $first_date->diff($second_date);

echo format_interval($difference);

Solution 4 - Php

View Hours and Minuts and Seconds..

$date1 = "2008-11-01 22:45:00"; 

$date2 = "2009-12-04 13:44:01"; 
 
$diff = abs(strtotime($date2) - strtotime($date1)); 
 
$years   = floor($diff / (365*60*60*24)); 
$months  = floor(($diff - $years * 365*60*60*24) / (30*60*60*24)); 
$days    = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24)/ (60*60*24));

$hours   = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24 - $days*60*60*24)/ (60*60)); 

$minuts  = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24 - $days*60*60*24 - $hours*60*60)/ 60); 

$seconds = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24 - $days*60*60*24 - $hours*60*60 - $minuts*60)); 
 
printf("%d years, %d months, %d days, %d hours, %d minuts\n, %d seconds\n", $years, $months, $days, $hours, $minuts, $seconds); 

Solution 5 - Php

Take a look at the following link. This is the best answer I've found so far.. :)

function dateDiff ($d1, $d2) {

    // Return the number of days between the two dates:    
    return round(abs(strtotime($d1) - strtotime($d2))/86400);

} // end function dateDiff

> It doesn't matter which date is earlier or later when you pass in the > date parameters. The function uses the PHP ABS() absolute value to > always return a postive number as the number of days between the two > dates. > > Keep in mind that the number of days between the two dates is NOT > inclusive of both dates. So if you are looking for the number of days > represented by all the dates between and including the dates entered, > you will need to add one (1) to the result of this function. > > For example, the difference (as returned by the above function) > between 2013-02-09 and 2013-02-14 is 5. But the number of days or > dates represented by the date range 2013-02-09 - 2013-02-14 is 6.

http://www.bizinfosys.com/php/date-difference.html

Solution 6 - Php

<?php
    $today = strtotime("2011-02-03 00:00:00");
    $myBirthDate = strtotime("1964-10-30 00:00:00");
    printf("Days since my birthday: ", ($today - $myBirthDate)/60/60/24);
?>

Solution 7 - Php

I voted for jurka's answer as that's my favorite, but I have a pre-php.5.3 version...

I found myself working on a similar problem - which is how I got to this question in the first place - but just needed a difference in hours. But my function solved this one pretty nicely as well and I don't have anywhere in my own library to keep it where it won't get lost and forgotten, so... hope this is useful to someone.

/**
 *
 * @param DateTime $oDate1
 * @param DateTime $oDate2
 * @return array 
 */
function date_diff_array(DateTime $oDate1, DateTime $oDate2) {
    $aIntervals = array(
        'year'   => 0,
        'month'  => 0,
        'week'   => 0,
        'day'    => 0,
        'hour'   => 0,
        'minute' => 0,
        'second' => 0,
    );
    
    foreach($aIntervals as $sInterval => &$iInterval) {
        while($oDate1 <= $oDate2){ 
            $oDate1->modify('+1 ' . $sInterval);
            if ($oDate1 > $oDate2) {
                $oDate1->modify('-1 ' . $sInterval);
                break;
            } else {
                $iInterval++;
            }
        }
    }
        
    return $aIntervals;
}

And the test:

$oDate = new DateTime();
$oDate->modify('+111402189 seconds');
var_dump($oDate);
var_dump(date_diff_array(new DateTime(), $oDate));

And the result:

object(DateTime)[2]
  public 'date' => string '2014-04-29 18:52:51' (length=19)
  public 'timezone_type' => int 3
  public 'timezone' => string 'America/New_York' (length=16)

array
  'year'   => int 3
  'month'  => int 6
  'week'   => int 1
  'day'    => int 4
  'hour'   => int 9
  'minute' => int 3
  'second' => int 8

I got the original idea from here, which I modified for my uses (and I hope my modification will show on that page as well).

You can very easily remove intervals you don't want (say "week") by removing them from the $aIntervals array, or maybe adding an $aExclude parameter, or just filter them out when you output the string.

Solution 8 - Php

I don't know if you are using a PHP framework or not, but a lot of PHP frameworks have date/time libraries and helpers to help keep you from reinventing the wheel.

For example CodeIgniter has the timespan() function. Simply input two Unix timestamps and it will automatically generate a result like this:

1 Year, 10 Months, 2 Weeks, 5 Days, 10 Hours, 16 Minutes

http://codeigniter.com/user_guide/helpers/date_helper.html

Solution 9 - Php

###Use example :

echo time_diff_string('2013-05-01 00:22:35', 'now');
echo time_diff_string('2013-05-01 00:22:35', 'now', true);

###Output :

4 months ago
4 months, 2 weeks, 3 days, 1 hour, 49 minutes, 15 seconds ago

###Function :

function time_diff_string($from, $to, $full = false) {
	$from = new DateTime($from);
	$to = new DateTime($to);
	$diff = $to->diff($from);
	
	$diff->w = floor($diff->d / 7);
	$diff->d -= $diff->w * 7;
	
	$string = array(
		'y' => 'year',
		'm' => 'month',
		'w' => 'week',
		'd' => 'day',
		'h' => 'hour',
		'i' => 'minute',
		's' => 'second',
	);
	foreach ($string as $k => &$v) {
		if ($diff->$k) {
			$v = $diff->$k . ' ' . $v . ($diff->$k > 1 ? 's' : '');
		} else {
			unset($string[$k]);
		}
	}

	if (!$full) $string = array_slice($string, 0, 1);
	return $string ? implode(', ', $string) . ' ago' : 'just now';
}

Solution 10 - Php

I would prefer to use date_create and date_diff objects.

Code:

$date1 = date_create("2007-03-24");
$date2 = date_create("2009-06-26");

$dateDifference = date_diff($date1, $date2)->format('%y years, %m months and %d days');

echo $dateDifference;

Output:

2 years, 3 months and 2 days

For more info read PHP date_diff manual

> According to manual date_diff is an alias of > DateTime::diff()

Solution 11 - Php

Here is the runnable code

$date1 = date_create('2007-03-24');
$date2 = date_create('2009-06-26');
$diff1 = date_diff($date1,$date2);
$daysdiff = $diff1->format("%R%a");
$daysdiff = abs($daysdiff);

Solution 12 - Php

I have some simple logic for that:

<?php
    per_days_diff('2011-12-12','2011-12-29')
    function per_days_diff($start_date, $end_date) {
        $per_days = 0;
        $noOfWeek = 0;
        $noOfWeekEnd = 0;
        $highSeason=array("7", "8");

        $current_date = strtotime($start_date);
        $current_date += (24 * 3600);
        $end_date = strtotime($end_date);

        $seassion = (in_array(date('m', $current_date), $highSeason))?"2":"1";

        $noOfdays = array('');

        while ($current_date <= $end_date) {
            if ($current_date <= $end_date) {
                $date = date('N', $current_date);
                array_push($noOfdays,$date);
                $current_date = strtotime('+1 day', $current_date);
            }
        }

        $finalDays = array_shift($noOfdays);
        //print_r($noOfdays);
        $weekFirst = array("week"=>array(),"weekEnd"=>array());
        for($i = 0; $i < count($noOfdays); $i++)
        {
            if ($noOfdays[$i] == 1)
            {
                //echo "This is week";
                //echo "<br/>";
                if($noOfdays[$i+6]==7)
                {
                    $noOfWeek++;
                    $i=$i+6;
                }
                else
                {
                    $per_days++;
                }
                //array_push($weekFirst["week"],$day);
            }
            else if($noOfdays[$i]==5)
            {
                //echo "This is weekend";
                //echo "<br/>";
                if($noOfdays[$i+2] ==7)
                {
                    $noOfWeekEnd++;
                    $i = $i+2;
                }
                else
                {
                    $per_days++;
                }
                //echo "After weekend value:- ".$i;
                //echo "<br/>";
            }
            else
            {
                $per_days++;
            }
        }

        /*echo $noOfWeek;
          echo "<br/>";
          echo $noOfWeekEnd;
          echo "<br/>";
          print_r($per_days);
          echo "<br/>";
          print_r($weekFirst);
        */

        $duration = array("weeks"=>$noOfWeek, "weekends"=>$noOfWeekEnd, "perDay"=>$per_days, "seassion"=>$seassion);
        return $duration;
      ?>

Solution 13 - Php

Try this very simple answer using date_diff(), this is tested.

$date1 = date_create("2017-11-27");
$date2 = date_create("2018-12-29");
$diff=date_diff($date1,$date2);
$months = $diff->format("%m months");
$years = $diff->format("%y years");
$days = $diff->format("%d days");

echo $years .' '.$months.' '.$days;

the output is:

1 years 1 months 2 days

Solution 14 - Php

You can use the

getdate()

function which returns an array containing all elements of the date/time supplied:

$diff = abs($endDate - $startDate);
$my_t=getdate($diff);
print("$my_t[year] years, $my_t[month] months and $my_t[mday] days");

If your start and end dates are in string format then use

$startDate = strtotime($startDateStr);
$endDate = strtotime($endDateStr);

before the above code

Solution 15 - Php

// If you just want to see the year difference then use this function.
// Using the logic I've created you may also create month and day difference
// which I did not provide here so you may have the efforts to use your brain.
// :)
$date1='2009-01-01';
$date2='2010-01-01';
echo getYearDifference ($date1,$date2);
function getYearDifference($date1=strtotime($date1),$date2=strtotime($date2)){
	$year = 0;
	while($date2 > $date1 = strtotime('+1 year', $date1)){
		++$year;
	}
	return $year;
}

Solution 16 - Php

This is my function. Required PHP >= 5.3.4. It use DateTime class. Very fast, quick and can do the difference between two dates or even the so called "time since".

if(function_exists('grk_Datetime_Since') === FALSE){
	function grk_Datetime_Since($From, $To='', $Prefix='', $Suffix=' ago', $Words=array()){
		#	Est-ce qu'on calcul jusqu'à un moment précis ? Probablement pas, on utilise maintenant
		if(empty($To) === TRUE){
			$To = time();
		}
		
		#	On va s'assurer que $From est numérique
		if(is_int($From) === FALSE){
			$From = strtotime($From);
		};
		
		#	On va s'assurer que $To est numérique
		if(is_int($To) === FALSE){
			$To = strtotime($To);
		}
		
		#	On a une erreur ?
		if($From === FALSE OR $From === -1 OR $To === FALSE OR $To === -1){
			return FALSE;
		}

		#	On va créer deux objets de date
		$From = new DateTime(@date('Y-m-d H:i:s', $From), new DateTimeZone('GMT'));
		$To   = new DateTime(@date('Y-m-d H:i:s', $To), new DateTimeZone('GMT'));
		
		#	On va calculer la différence entre $From et $To
		if(($Diff = $From->diff($To)) === FALSE){
			return FALSE;
		}
		
		#	On va merger le tableau des noms (par défaut, anglais)
		$Words = array_merge(array(
			'year'		=> 'year',
			'years'		=> 'years',
			'month'		=> 'month',
			'months'	=> 'months',
			'week'		=> 'week',
			'weeks'		=> 'weeks',
			'day'		=> 'day',
			'days'		=> 'days',
			'hour'		=> 'hour',
			'hours'		=> 'hours',
			'minute'	=> 'minute',
			'minutes'	=> 'minutes',
			'second'	=> 'second',
			'seconds'	=> 'seconds'
		), $Words);
		
		#	On va créer la chaîne maintenant
		if($Diff->y > 1){
			$Text = $Diff->y.' '.$Words['years'];
		} elseif($Diff->y == 1){
			$Text = '1 '.$Words['year'];
		} elseif($Diff->m > 1){
			$Text = $Diff->m.' '.$Words['months'];
		} elseif($Diff->m == 1){
			$Text = '1 '.$Words['month'];
		} elseif($Diff->d > 7){
			$Text = ceil($Diff->d/7).' '.$Words['weeks'];
		} elseif($Diff->d == 7){
			$Text = '1 '.$Words['week'];
		} elseif($Diff->d > 1){
			$Text = $Diff->d.' '.$Words['days'];
		} elseif($Diff->d == 1){
			$Text = '1 '.$Words['day'];
		} elseif($Diff->h > 1){
			$Text = $Diff->h.' '.$Words['hours'];
		} elseif($Diff->h == 1){
			$Text = '1 '.$Words['hour'];
		} elseif($Diff->i > 1){
			$Text = $Diff->i.' '.$Words['minutes'];
		} elseif($Diff->i == 1){
			$Text = '1 '.$Words['minute'];
		} elseif($Diff->s > 1){
			$Text = $Diff->s.' '.$Words['seconds'];
		} else {
			$Text = '1 '.$Words['second'];
		}

		return $Prefix.$Text.$Suffix;
	}
}

Solution 17 - Php

you can always use the following function that can return the age in years and months (ie. 1 Year 4 Months)

function getAge($dob, $age_at_date)
{  
    $d1 = new DateTime($dob);
    $d2 = new DateTime($age_at_date);
    $age = $d2->diff($d1);
	$years = $age->y;
	$months = $age->m;
	
	return $years.'.'.months;
}

or if you want the age to be calculated at the current date, you can use

function getAge($dob)
{  
    $d1 = new DateTime($dob);
    $d2 = new DateTime(date());
    $age = $d2->diff($d1);
	$years = $age->y;
	$months = $age->m;
	
	return $years.'.'.months;
}

Solution 18 - Php

I found your article on the following page, which contains a number of references for PHP date time calculations.

Calculate the difference between two Dates (and time) using PHP. The following page provides a range of different methods (7 in total) for performing date / time calculations using PHP, to determine the difference in time (hours, munites), days, months or years between two dates.

See PHP Date Time – 7 Methods to Calculate the Difference between 2 dates.

Solution 19 - Php

This will try to detect whether a timestamp was given or not, and will also return future dates/times as negative values:

<?php

function time_diff($start, $end = NULL, $convert_to_timestamp = FALSE) {
  // If $convert_to_timestamp is not explicitly set to TRUE,
  // check to see if it was accidental:
  if ($convert_to_timestamp || !is_numeric($start)) {
    // If $convert_to_timestamp is TRUE, convert to timestamp:
    $timestamp_start = strtotime($start);
  }
  else {
    // Otherwise, leave it as a timestamp:
    $timestamp_start = $start;
  }
  // Same as above, but make sure $end has actually been overridden with a non-null,
  // non-empty, non-numeric value:
  if (!is_null($end) && (!empty($end) && !is_numeric($end))) {
    $timestamp_end = strtotime($end);
  }
  else {
    // If $end is NULL or empty and non-numeric value, assume the end time desired
    // is the current time (useful for age, etc):
    $timestamp_end = time();
  }
  // Regardless, set the start and end times to an integer:
  $start_time = (int) $timestamp_start;
  $end_time = (int) $timestamp_end;

  // Assign these values as the params for $then and $now:
  $start_time_var = 'start_time';
  $end_time_var = 'end_time';
  // Use this to determine if the output is positive (time passed) or negative (future):
  $pos_neg = 1;

  // If the end time is at a later time than the start time, do the opposite:
  if ($end_time <= $start_time) {
    $start_time_var = 'end_time';
    $end_time_var = 'start_time';
    $pos_neg = -1;
  }

  // Convert everything to the proper format, and do some math:
  $then = new DateTime(date('Y-m-d H:i:s', $$start_time_var));
  $now = new DateTime(date('Y-m-d H:i:s', $$end_time_var));

  $years_then = $then->format('Y');
  $years_now = $now->format('Y');
  $years = $years_now - $years_then;

  $months_then = $then->format('m');
  $months_now = $now->format('m');
  $months = $months_now - $months_then;

  $days_then = $then->format('d');
  $days_now = $now->format('d');
  $days = $days_now - $days_then;

  $hours_then = $then->format('H');
  $hours_now = $now->format('H');
  $hours = $hours_now - $hours_then;

  $minutes_then = $then->format('i');
  $minutes_now = $now->format('i');
  $minutes = $minutes_now - $minutes_then;

  $seconds_then = $then->format('s');
  $seconds_now = $now->format('s');
  $seconds = $seconds_now - $seconds_then;

  if ($seconds < 0) {
    $minutes -= 1;
    $seconds += 60;
  }
  if ($minutes < 0) {
    $hours -= 1;
    $minutes += 60;
  }
  if ($hours < 0) {
    $days -= 1;
    $hours += 24;
  }
  $months_last = $months_now - 1;
  if ($months_now == 1) {
    $years_now -= 1;
    $months_last = 12;
  }

  // "Thirty days hath September, April, June, and November" ;)
  if ($months_last == 9 || $months_last == 4 || $months_last == 6 || $months_last == 11) {
    $days_last_month = 30;
  }
  else if ($months_last == 2) {
    // Factor in leap years:
    if (($years_now % 4) == 0) {
      $days_last_month = 29;
    }
    else {
      $days_last_month = 28;
    }
  }
  else {
    $days_last_month = 31;
  }
  if ($days < 0) {
    $months -= 1;
    $days += $days_last_month;
  }
  if ($months < 0) {
    $years -= 1;
    $months += 12;
  }

  // Finally, multiply each value by either 1 (in which case it will stay the same),
  // or by -1 (in which case it will become negative, for future dates).
  // Note: 0 * 1 == 0 * -1 == 0
  $out = new stdClass;
  $out->years = (int) $years * $pos_neg;
  $out->months = (int) $months * $pos_neg;
  $out->days = (int) $days * $pos_neg;
  $out->hours = (int) $hours * $pos_neg;
  $out->minutes = (int) $minutes * $pos_neg;
  $out->seconds = (int) $seconds * $pos_neg;
  return $out;
}

Example usage:

<?php
  $birthday = 'June 2, 1971';
  $check_age_for_this_date = 'June 3, 1999 8:53pm';
  $age = time_diff($birthday, $check_age_for_this_date)->years;
  print $age;// 28

Or:

<?php
  $christmas_2020 = 'December 25, 2020';
  $countdown = time_diff($christmas_2020);
  print_r($countdown);

Solution 20 - Php

"if" the date is stored in MySQL, I find it easier to do the difference calculation at the database level... Then based on the Day, Hour, Min, Sec output, parse and display results as appropriate...

mysql> select firstName, convert_tz(loginDate, '+00:00', '-04:00') as loginDate, TIMESTAMPDIFF(DAY, loginDate, now()) as 'Day', TIMESTAMPDIFF(HOUR, loginDate, now())+4 as 'Hour', TIMESTAMPDIFF(MINUTE, loginDate, now())+(60*4) as 'Min', TIMESTAMPDIFF(SECOND, loginDate, now())+(60*60*4) as 'Sec' from User_ where userId != '10158' AND userId != '10198' group by emailAddress order by loginDate desc;
 +-----------+---------------------+------+------+------+--------+
 | firstName | loginDate           | Day  | Hour | Min  | Sec    |
 +-----------+---------------------+------+------+------+--------+
 | Peter     | 2014-03-30 18:54:40 |    0 |    4 |  244 |  14644 |
 | Keith     | 2014-03-30 18:54:11 |    0 |    4 |  244 |  14673 |
 | Andres    | 2014-03-28 09:20:10 |    2 |   61 | 3698 | 221914 |
 | Nadeem    | 2014-03-26 09:33:43 |    4 |  109 | 6565 | 393901 |
 +-----------+---------------------+------+------+------+--------+
 4 rows in set (0.00 sec)

Solution 21 - Php

For php version >=5.3 : Create two date objects and then use date_diff() function. It will return php DateInterval object. see documentation

$date1=date_create("2007-03-24");
$date2=date_create("2009-06-26");
$diff=date_diff($date1,$date2);
echo $diff->format("%R%a days");

Solution 22 - Php

use this function

//function Diff between Dates
//////////////////////////////////////////////////////////////////////
//PARA: Date Should In YYYY-MM-DD Format
//RESULT FORMAT:
// '%y Year %m Month %d Day %h Hours %i Minute %s Seconds' =>  1 Year 3 Month 14 Day 11 Hours 49 Minute 36 Seconds
// '%y Year %m Month %d Day'                       =>  1 Year 3 Month 14 Days
// '%m Month %d Day'                                     =>  3 Month 14 Day
// '%d Day %h Hours'                                   =>  14 Day 11 Hours
// '%d Day'                                                 =>  14 Days
// '%h Hours %i Minute %s Seconds'         =>  11 Hours 49 Minute 36 Seconds
// '%i Minute %s Seconds'                           =>  49 Minute 36 Seconds
// '%h Hours                                          =>  11 Hours
// '%a Days                                                =>  468 Days
//////////////////////////////////////////////////////////////////////
function dateDifference($date_1 , $date_2 , $differenceFormat = '%a' )
{
    $datetime1 = date_create($date_1);
    $datetime2 = date_create($date_2);

    $interval = date_diff($datetime1, $datetime2);

    return $interval->format($differenceFormat);

}

only set parameter $differenceFormat As your need example I want Diff between to years with months and days your age

dateDifference(date('Y-m-d') , $date , '%y %m %d')

or other format

dateDifference(date('Y-m-d') , $date , '%y-%m-%d')

Solution 23 - Php

An easy function

function time_difference($time_1, $time_2, $limit = null)
{

    $val_1 = new DateTime($time_1);
    $val_2 = new DateTime($time_2);

    $interval = $val_1->diff($val_2);

    $output = array(
        "year" => $interval->y,
        "month" => $interval->m,
        "day" => $interval->d,
        "hour" => $interval->h,
        "minute" => $interval->i,
        "second" => $interval->s
    );

    $return = "";
    foreach ($output AS $key => $value) {

        if ($value == 1)
            $return .= $value . " " . $key . " ";
        elseif ($value >= 1)
            $return .= $value . " " . $key . "s ";

        if ($key == $limit)
            return trim($return);
    }
    return trim($return);
}

Use like

echo time_difference ($time_1, $time_2, "day");

Will return like 2 years 8 months 2 days

Solution 24 - Php

You can also use following code to return date diff by round fractions up $date1 = $duedate; // assign due date echo $date2 = date("Y-m-d"); // current date $ts1 = strtotime($date1); $ts2 = strtotime($date2); $seconds_diff = $ts1 - $ts2; echo $datediff = ceil(($seconds_diff/3600)/24); // return in days

If you use floor method of php instead of ceil it will return you the round fraction down. Please check the difference here, some times if your staging servers timezone is different then the live site time zone in that case you may get different results so change the conditions accordingly.

Solution 25 - Php

$date1 = date_create('2007-03-24');
$date2 = date_create('2009-06-26');
$interval = date_diff($date1, $date2);
echo "difference : " . $interval->y . " years, " . $interval->m." months, ".$interval->d." days ";

Solution 26 - Php

Some time ago I wrote a format_date function as this gives many options on how you want your date:

function format_date($date, $type, $seperator="-")
{
    if($date)
    {
        $day = date("j", strtotime($date));
        $month = date("n", strtotime($date));
        $year = date("Y", strtotime($date));
        $hour = date("H", strtotime($date));
        $min = date("i", strtotime($date));
        $sec = date("s", strtotime($date));
        
        switch($type)
        {
            case 0:  $date = date("Y".$seperator."m".$seperator."d",mktime($hour, $min, $sec, $month, $day, $year)); break;
            case 1:  $date = date("D, F j, Y",mktime($hour, $min, $sec, $month, $day, $year)); break;
            case 2:  $date = date("d".$seperator."m".$seperator."Y",mktime($hour, $min, $sec, $month, $day, $year)); break;
            case 3:  $date = date("d".$seperator."M".$seperator."Y",mktime($hour, $min, $sec, $month, $day, $year)); break;
            case 4:  $date = date("d".$seperator."M".$seperator."Y h:i A",mktime($hour, $min, $sec, $month, $day, $year)); break;
            case 5:  $date = date("m".$seperator."d".$seperator."Y",mktime($hour, $min, $sec, $month, $day, $year)); break;
            case 6:  $date = date("M",mktime($hour, $min, $sec, $month, $day, $year)); break;
            case 7:  $date = date("Y",mktime($hour, $min, $sec, $month, $day, $year)); break;
            case 8:  $date = date("j",mktime($hour, $min, $sec, $month, $day, $year)); break;
            case 9:  $date = date("n",mktime($hour, $min, $sec, $month, $day, $year)); break;
            case 10: 
                     $diff = abs(strtotime($date) - strtotime(date("Y-m-d h:i:s"))); 
                     $years = floor($diff / (365*60*60*24));
                     $months = floor(($diff - $years * 365*60*60*24) / (30*60*60*24));
                     $days = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24)/ (60*60*24));
                     $date = $years . " years, " . $months . " months, " . $days . "days";
        }
    }
    return($date);
}    

Solution 27 - Php

I had the same problem with PHP 5.2 and solved it with MySQL. Might not be exactly what you're looking for, but this will do the trick and return the number of days:

$datediff_q = $dbh->prepare("SELECT DATEDIFF(:date2, :date1)");
$datediff_q->bindValue(':date1', '2007-03-24', PDO::PARAM_STR);
$datediff_q->bindValue(':date2', '2009-06-26', PDO::PARAM_STR);
$datediff = ($datediff_q->execute()) ? $datediff_q->fetchColumn(0) : false;

More info here http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_datediff

Solution 28 - Php

Since everyone is posting code samples, here is another version.

I wanted a function to display differences from seconds to years (just one unit). For periods over 1 day, I wanted it to rollover at midnight (10am Monday seen from 9am Wednesday is 2 days ago, not 1). And for periods over a month, I wanted the rollover to be on the same day of the month (including for 30/31 day months & leap years).

This is what I came up with:

/**
 * Returns how long ago something happened in the past, showing it
 * as n seconds / minutes / hours / days / weeks / months / years ago.
 *
 * For periods over a day, it rolls over at midnight (so doesn't depend
 * on current time of day), and it correctly accounts for month-lengths
 * and leap-years (months and years rollover on current day of month).
 *
 * $param string $timestamp in DateTime format
 * $return string description of interval
 */
function ago($timestamp)
{
    $then = date_create($timestamp);

    // for anything over 1 day, make it rollover on midnight
    $today = date_create('tomorrow'); // ie end of today
    $diff = date_diff($then, $today);

    if ($diff->y > 0) return $diff->y.' year'.($diff->y>1?'s':'').' ago';
    if ($diff->m > 0) return $diff->m.' month'.($diff->m>1?'s':'').' ago';
    $diffW = floor($diff->d / 7);
    if ($diffW > 0) return $diffW.' week'.($diffW>1?'s':'').' ago';
    if ($diff->d > 1) return $diff->d.' day'.($diff->d>1?'s':'').' ago';

    // for anything less than 1 day, base it off 'now'
    $now = date_create();
    $diff = date_diff($then, $now);

    if ($diff->d > 0) return 'yesterday';
    if ($diff->h > 0) return $diff->h.' hour'.($diff->h>1?'s':'').' ago';
    if ($diff->i > 0) return $diff->i.' minute'.($diff->i>1?'s':'').' ago';
    return $diff->s.' second'.($diff->s==1?'':'s').' ago';
}

Solution 29 - Php

Very simple:

    <?php
        $date1 = date_create("2007-03-24");
        echo "Start date: ".$date1->format("Y-m-d")."<br>";
        $date2 = date_create("2009-06-26");
        echo "End date: ".$date2->format("Y-m-d")."<br>";
        $diff = date_diff($date1,$date2);
        echo "Difference between start date and end date: ".$diff->format("%y years, %m months and %d days")."<br>";
    ?>
    

Please checkout the following link for details:

PHP: date_diff - Manual

Note that it's for PHP 5.3.0 or greater.

Solution 30 - Php

I'm using the following function which I wrote, when PHP 5.3 (respectively date_diff()) is not available:

		function dateDifference($startDate, $endDate)
		{
			$startDate = strtotime($startDate);
			$endDate = strtotime($endDate);
			if ($startDate === false || $startDate < 0 || $endDate === false || $endDate < 0 || $startDate > $endDate)
				return false;
				
			$years = date('Y', $endDate) - date('Y', $startDate);
			
			$endMonth = date('m', $endDate);
			$startMonth = date('m', $startDate);
			
			// Calculate months
			$months = $endMonth - $startMonth;
			if ($months <= 0)  {
				$months += 12;
				$years--;
			}
			if ($years < 0)
				return false;
			
			// Calculate the days
			$measure = ($months == 1) ? 'month' : 'months';
			$days = $endDate - strtotime('+' . $months . ' ' . $measure, $startDate);
			$days = date('z', $days);	
						
			return array($years, $months, $days);
		}

Solution 31 - Php

DateInterval is great but it has a couple of caveats:

  1. only for PHP 5.3+ (but that's really not a good excuse anymore)
  2. only supports years, months, days, hours, minutes and seconds (no weeks)
  3. it calculates the difference with all of the above + days (you can't get the difference in months only)

To overcome that, I coded the following (improved from @enobrev answer):

function date_dif($since, $until, $keys = 'year|month|week|day|hour|minute|second')
{
	$date = array_map('strtotime', array($since, $until));
	
	if ((count($date = array_filter($date, 'is_int')) == 2) && (sort($date) === true))
	{
		$result = array_fill_keys(explode('|', $keys), 0);
		
		foreach (preg_grep('~^(?:year|month)~i', $result) as $key => $value)
		{
			while ($date[1] >= strtotime(sprintf('+%u %s', $value + 1, $key), $date[0]))
			{
				++$value;
			}

			$date[0] = strtotime(sprintf('+%u %s', $result[$key] = $value, $key), $date[0]);
		}

		foreach (preg_grep('~^(?:year|month)~i', $result, PREG_GREP_INVERT) as $key => $value)
		{
			if (($value = intval(abs($date[0] - $date[1]) / strtotime(sprintf('%u %s', 1, $key), 0))) > 0)
			{
				$date[0] = strtotime(sprintf('+%u %s', $result[$key] = $value, $key), $date[0]);
			}
		}

		return $result;
	}

	return false;
}

It runs two loops; the first one deals with the relative intervals (years and months) via brute-forcing, and the second one computes the additional absolute intervals with simple arithmetic (so it's faster):

echo humanize(date_dif('2007-03-24', '2009-07-31', 'second')); // 74300400 seconds
echo humanize(date_dif('2007-03-24', '2009-07-31', 'minute|second')); // 1238400 minutes, 0 seconds
echo humanize(date_dif('2007-03-24', '2009-07-31', 'hour|minute|second')); // 20640 hours, 0 minutes, 0 seconds
echo humanize(date_dif('2007-03-24', '2009-07-31', 'year|day')); // 2 years, 129 days
echo humanize(date_dif('2007-03-24', '2009-07-31', 'year|week')); // 2 years, 18 weeks
echo humanize(date_dif('2007-03-24', '2009-07-31', 'year|week|day')); // 2 years, 18 weeks, 3 days
echo humanize(date_dif('2007-03-24', '2009-07-31')); // 2 years, 4 months, 1 week, 0 days, 0 hours, 0 minutes, 0 seconds

function humanize($array)
{
	$result = array();

	foreach ($array as $key => $value)
	{
		$result[$key] = $value . ' ' . $key;

		if ($value != 1)
		{
			$result[$key] .= 's';
		}
	}

	return implode(', ', $result);
}

Solution 32 - Php

In for a penny, in for a pound: I have just reviewed several solutions, all providing a complex solution using floor() that then rounds up to a 26 years 12 month and 2 days solution, for what should have been 25 years, 11 months and 20 days!!!!

here is my version of this problem: may not be elegant, may not be well coded, but provides a more closer proximity to a answer if you do not count LEAP years, obviously leap years could be coded into this, but in this case - as someone else said, perhaps you could provide this answer:: I have included all TEST conditions and print_r so that you can see more clearly the construct of the results:: here goes,

// set your input dates/ variables::

$ISOstartDate 	= "1987-06-22";
$ISOtodaysDate = "2013-06-22";

// We need to EXPLODE the ISO yyyy-mm-dd format into yyyy mm dd, as follows::

$yDate[ ] = explode('-', $ISOstartDate); print_r ($yDate);

$zDate[ ] = explode('-', $ISOtodaysDate); print_r ($zDate);

// Lets Sort of the Years!
// Lets Sort out the difference in YEARS between startDate and todaysDate ::
$years = $zDate[0][0] - $yDate[0][0];

// We need to collaborate if the month = month = 0, is before or after the Years Anniversary ie 11 months 22 days or 0 months 10 days...
if ($months == 0 and $zDate[0][1] > $ydate[0][1]) {
	$years = $years -1;
}
// TEST result
echo "\nCurrent years => ".$years;

// Lets Sort out the difference in MONTHS between startDate and todaysDate ::
$months = $zDate[0][1] - $yDate[0][1];

// TEST result
echo "\nCurrent months => ".$months;

// Now how many DAYS has there been - this assumes that there is NO LEAP years, so the calculation is APPROXIMATE not 100%
// Lets cross reference the startDates Month = how many days are there in each month IF m-m = 0 which is a years anniversary
// We will use a switch to check the number of days between each month so we can calculate days before and after the years anniversary

switch ($yDate[0][1]){
	case 01: 	$monthDays = '31'; 	break; 	// Jan
	case 02: 	$monthDays = '28'; 	break; 	// Feb
	case 03: 	$monthDays = '31'; 	break;	// Mar
	case 04: 	$monthDays = '30'; 	break;	// Apr
	case 05: 	$monthDays = '31'; 	break;	// May
	case 06: 	$monthDays = '30'; 	break;	// Jun
	case 07: 	$monthDays = '31'; 	break;	// Jul
	case 08: 	$monthDays = '31'; 	break;	// Aug
	case 09: 	$monthDays = '30'; 	break;	// Sept
	case 10: 	$monthDays = '31'; 	break;	// Oct
	case 11: 	$monthDays = '30'; 	break;	// Nov
	case 12: 	$monthDays = '31'; 	break;	// Dec
};
// TEST return
echo "\nDays in start month ".$yDate[0][1]." => ".$monthDays;
	
	
// Lets correct the problem with 0 Months - is it 11 months + days, or 0 months +days???

$days = $zDate[0][2] - $yDate[0][2] +$monthDays;
echo "\nCurrent days => ".$days."\n";

// Lets now Correct the months to being either 11 or 0 Months, depending upon being + or - the years Anniversary date 
// At the same time build in error correction for Anniversary dates not being 1yr 0m 31d... see if ($days == $monthDays )
if($days < $monthDays && $months == 0)
	{
	$months = 11; 		// If Before the years anniversary date
	}
else	{
	$months = 0;		// If After the years anniversary date
	$years = $years+1;	// Add +1 to year
    $days = $days-$monthDays;	// Need to correct days to how many days after anniversary date
	};
// Day correction for Anniversary dates
if ($days == $monthDays )	// if todays date = the Anniversary DATE! set days to ZERO
	{
	$days = 0;			// days set toZERO so 1 years 0 months 0 days
	};

    echo "\nTherefore, the number of years/ months/ days/ \nbetween start and todays date::\n\n";

    printf("%d years, %d months, %d days\n", $years, $months, $days);

the end result is:: 26 years, 0 months, 0 days

That's how long I have been in business for on the 22nd June 2013 - Ouch!

Solution 33 - Php

$date = '2012.11.13';
$dateOfReturn = '2017.10.31';

$substract = str_replace('.', '-', $date);

$substract2 = str_replace('.', '-', $dateOfReturn);



$date1 = $substract;
$date2 = $substract2;

$ts1 = strtotime($date1);
$ts2 = strtotime($date2);

$year1 = date('Y', $ts1);
$year2 = date('Y', $ts2);

$month1 = date('m', $ts1);
$month2 = date('m', $ts2);

echo $diff = (($year2 - $year1) * 12) + ($month2 - $month1);

Solution 34 - Php

I'd like to bring a slightly different perspective, which seemingly hasn't been mentioned.

You could solve this problem (just like any other) in a declarative way. The point is asking what you need, not how to get there.

Here, you need a difference. But what is that difference? It's an interval, as already mentioned in the most upvoted answer. The thing is how to get it. Instead of explicitly invoking diff() method, you could just create an interval by start date and finish date, that is, by date range:

$startDate = '2007-03-24';
$endDate = '2009-06-26';
$range = new FromRange(new ISO8601DateTime($startDate), new ISO8601DateTime($endDate));

All the intricacies such as a leap year and all are already taken care of. Now when you have an interval with fixed start datetime, you can get a human-readable version:

var_dump((new HumanReadable($range))->value());

It outputs exactly what you need.

If you need some customized format, it's not a problem either. You can use a ISO8601Formatted class which accepts a callable with six arguments: year, month, day, hour, minute, and second:

(new ISO8601Formatted(
    new FromRange(
        new ISO8601DateTime('2017-07-03T14:27:39+00:00'),
        new ISO8601DateTime('2018-07-05T14:27:39.235487+00:00')
    ),
    function (int $years, int $months, int $days, int $hours, int $minutes, int $seconds) {
        return $years >= 1 ? 'More than a year' : 'Less than a year';
    }
))
    ->value();

It outputs More than a year.

For more about this approach, take a look at a quick start entry.

Solution 35 - Php

function showTime($time){

    $start      = strtotime($time);
    $end        = strtotime(date("Y-m-d H:i:s"));
    $minutes    = ($end - $start)/60;


    // years 
    if(($minutes / (60*24*365)) > 1){
        $years = floor($minutes/(60*24*365));
        return "From $years year( s ) ago";
    }


    // monthes 
    if(($minutes / (60*24*30)) > 1){
        $monthes = floor($minutes/(60*24*30));
        return "From $monthes monthe( s ) ago";
    }


    // days 
    if(($minutes / (60*24)) > 1){
        $days = floor($minutes/(60*24));
        return "From $days day( s ) ago";
    }

    // hours 
    if(($minutes / 60) > 1){
        $hours = floor($minutes/60);
        return "From $hours hour( s ) ago";
    }

    // minutes 
    if($minutes > 1){
        $minutes = floor($minutes);
        return "From $minutes minute( s ) ago";
    }
}

echo showTime('2022-05-05 21:33:00');

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiongnaneshView Question on Stackoverflow
Solution 1 - PhpjurkaView Answer on Stackoverflow
Solution 2 - PhpEmil HView Answer on Stackoverflow
Solution 3 - PhpMadara's GhostView Answer on Stackoverflow
Solution 4 - PhpkhaldonnoView Answer on Stackoverflow
Solution 5 - Phpcasper123View Answer on Stackoverflow
Solution 6 - PhpvengatView Answer on Stackoverflow
Solution 7 - PhpenobrevView Answer on Stackoverflow
Solution 8 - PhpJake WilsonView Answer on Stackoverflow
Solution 9 - PhpGlavićView Answer on Stackoverflow
Solution 10 - PhpAdeelView Answer on Stackoverflow
Solution 11 - PhpMosinView Answer on Stackoverflow
Solution 12 - PhpHardik RavalView Answer on Stackoverflow
Solution 13 - PhplarpView Answer on Stackoverflow
Solution 14 - PhpMark PimView Answer on Stackoverflow
Solution 15 - PhpescView Answer on Stackoverflow
Solution 16 - PhpDavid BélangerView Answer on Stackoverflow
Solution 17 - PhpRickus HarmseView Answer on Stackoverflow
Solution 18 - PhpJames - Php DevelopmentView Answer on Stackoverflow
Solution 19 - PhpjerdiggityView Answer on Stackoverflow
Solution 20 - PhpElasticThoughtsView Answer on Stackoverflow
Solution 21 - Phpbikram kcView Answer on Stackoverflow
Solution 22 - PhpWaad MawloodView Answer on Stackoverflow
Solution 23 - PhpAnujView Answer on Stackoverflow
Solution 24 - PhpRikin AdhyapakView Answer on Stackoverflow
Solution 25 - PhplizaView Answer on Stackoverflow
Solution 26 - PhpGajendraSinghPariharView Answer on Stackoverflow
Solution 27 - PhpKlemen TusarView Answer on Stackoverflow
Solution 28 - PhpChrisVView Answer on Stackoverflow
Solution 29 - PhpChoudhury Saadmaan MahmidView Answer on Stackoverflow
Solution 30 - PhpKonstantin ShegunovView Answer on Stackoverflow
Solution 31 - PhpAlix AxelView Answer on Stackoverflow
Solution 32 - Phpuser2169219View Answer on Stackoverflow
Solution 33 - PhpAbhijitView Answer on Stackoverflow
Solution 34 - PhpVadim SamokhinView Answer on Stackoverflow
Solution 35 - Phpmostafa aliView Answer on Stackoverflow