Лучший способ действия - использовать объекты PHP DateTime
(и DateInterval
). Каждая дата инкапсулируется в объект DateTime
, и тогда может быть сделана разница между двумя:
$first_date = new DateTime("2012-11-30 17:03:30");
$second_date = new DateTime("2012-12-21 00:00:00");
Объект DateTime
будет принимать любой формат strtotime()
. Если требуется более конкретный формат даты, DateTime::createFromFormat()
можно использовать для создания объекта DateTime
.
После того, как оба объекта были созданы, вы вычтите один из другого с DateTime::diff()
.
$difference = $first_date->diff($second_date);
$difference
теперь содержит объект DateInterval
с информацией о разности. A var_dump()
выглядит так:
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
Чтобы отформатировать объект DateInterval
, нам нужно проверить каждое значение и исключить его, если оно равно 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;
}
Осталось только называть нашу функцию объектом $difference
DateInterval
:
echo format_interval($difference);
И мы получаем правильный результат:
20 дней 6 часов 56 минут 30 секунд
Полный код, используемый для достижения цели:
/** * 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);