Как рассчитать разницу между датами в PHP?

как рассчитать разницу между датами в php?

Принцип вычисления разности дат

Нет ничего сложного, если вам необходимо вычислить разность UTC-меток. Они представлены в виде целочисленных значений, отображающих количество секунд прошедших с 1 января 1970года. Началом их точки отсчета является часовой пояс, лежащий на долготе 0 градусов. Временные метки не чувствительны к переходам на летнее и зимнее время. Обычная арифметическая операция разности конечной и начальной метки покажет, сколько секунд длился заданный интервал.

Гораздо более специфичной задачей является вычисление разницы между датами, представленными в виде строк. В PHP для этого используются объекты класса DateTime(). Мы уже успели познакомиться с данным классом в уроке о преобразовании временных меток.

Для вычисления разницы дат создайте два объекта DateTime(). У объекта, отвечающего за конечную точку временного промежутка, необходимо вызвать метод diff() с передачей объекта, хранящего дату начала. Результатом вызова метода diff() будет объект класса DateInterval().

$startDate = new DateTime('1965-05-10 7:32:56pm', new DateTimeZone('America/New_York'));
$endDate = new DateTime('1962-11-20 4:29:11am', new DateTimeZone('America/New_York'));

$diff = $endDate->diff($startDate);

echo "
    Прошло:<br/>
        Дней - ". $diff->format('%a') ."<br/>
        Часов - ". $diff->format('%h') ."<br/>
        Минут - ". $diff->format('%i') ."<br/>
        Секунд - ". $diff->format('%i') ."<br/>
";

Проблема некорректности расчетов

В примере, приведенном выше, мы получили желаемый результат. Однако в нем присутствует незаметная на первый взгляд ошибка. В заданном промежутке дат был переход на зимнее время. Поэтому DateInterval() показал нам «лишний час».

Чтобы избежать таких ошибок. Необходимо сравнивать объекты DateTime() сгенерированные не из строкового представления даты, а из временных меток. В следующем примере мы дополнили программный код. Он стал запутаннее. Однако разница между датами теперь вычисляется корректно.

Обратите внимание, что перед передачей временной метки в конструктор DateTime() она преобразуется к строке вида «@временная_метка». Знак «@» является специальным и говорит о том, что следующее за ним значение нужно принимать за UTC-метку.

$startDate = new DateTime('1965-05-10 7:32:56pm', new DateTimeZone('America/New_York'));
$startDate = new DateTime('@'. $startDate->getTimestamp());

$endDate = new DateTime('1962-11-20 4:29:11am', new DateTimeZone('America/New_York'));
$endDate = new DateTime('@'. $endDate->getTimestamp());

$diff = $endDate->diff($startDate);

echo "
    Прошло:<br/>
        Дней - ". $diff->format('%a') ."<br/>
        Часов - ". $diff->format('%h') ."<br/>
        Минут - ". $diff->format('%i') ."<br/>
        Секунд - ". $diff->format('%i') ."<br/>
";

Заметка
Некорректный расчет интервалов из строковых представлений дат не является ошибкой PHP. Так работают функции даты и времени во всех языках программирования.

Последние публикации