Разница между датами в PHP: 5 подходов от простого к профессиональному

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Как вычислить разницу между двумя датами в PHP: от новичка до профи

Вы когда-нибудь задавались вопросом: «Сколько дней прошло с моего последнего отпуска?» или «Через сколько часов закончится акция на сайте?»? Если вы PHP-разработчик, то эти вопросы превращаются в одну задачу: как вычислить разницу между двумя датами.

Этот вопрос — один из самых популярных на Stack Overflow с тысячами просмотров. И неспроста: работа с датами в PHP может быть коварной. Високосные годы, часовые пояса, разные форматы — всё это способно сломать даже самый продуманный код.

В этой статье мы разберём 5 проверенных способов вычисления разницы между датами в PHP — от простейших до профессиональных. Вы узнаете, когда какой метод использовать, и получите готовые примеры кода.

1. Классический метод: strtotime() и простая арифметика

Самый старый и интуитивно понятный способ — перевести даты в Unix-метки (timestamp) с помощью функции strtotime() и просто вычесть одно число из другого.

<?php
$date1 = strtotime('2024-01-15');
$date2 = strtotime('2024-03-20');

$diff_seconds = $date2 - $date1;
$diff_days = floor($diff_seconds / (60 * 60 * 24));

echo "Разница в днях: " . $diff_days; // Выведет: 65
?>

Плюсы: простота, работает в любой версии PHP.

Минусы: не учитывает часовые пояса, проблемы с датами до 1970 года, нет встроенной поддержки месяцев и лет (ведь их длина варьируется).

Этот метод подходит для быстрых расчётов «на коленке», но для серьёзных проектов лучше использовать более современные инструменты.

2. Современный стандарт: класс DateTime и метод diff()

Начиная с PHP 5.2, у нас есть мощный класс DateTime. Это настоящий швейцарский нож для работы с датами. Метод diff() возвращает объект DateInterval, который содержит всю информацию о разнице.

<?php
$date1 = new DateTime('2024-01-15');
$date2 = new DateTime('2024-03-20');

$interval = $date1->diff($date2);

echo "Разница: " . $interval->days . " дней"; // 65
echo "или " . $interval->m . " месяцев и " . $interval->d . " дней"; // 2 месяца и 5 дней
?>

DateInterval даёт доступ к таким свойствам:

  • y — годы
  • m — месяцы
  • d — дни
  • h — часы
  • i — минуты
  • s — секунды
  • days — общее количество дней (самое полезное!)
  • invert — флаг: 0 если первая дата раньше, 1 если позже

Этот метод учитывает високосные годы и корректно работает с разными календарными особенностями. Именно его рекомендуют в официальной документации PHP.

3. Форматирование разницы: как вывести «2 года 3 месяца 10 дней»

Часто нужно не просто получить число, а красиво отформатировать разницу для пользователя. Метод format() объекта DateInterval приходит на помощь.

<?php
$birthday = new DateTime('1990-05-15');
$today = new DateTime();

$age = $birthday->diff($today);

echo $age->format('%y лет %m месяцев %d дней');
// Пример: 34 лет 2 месяцев 3 дней
?>

Спецификаторы формата:

  • %y — годы
  • %m — месяцы
  • %d — дни
  • %h — часы
  • %i — минуты
  • %s — секунды
  • %a — общее количество дней (альтернатива days)
  • %r — знак "минус" если разница отрицательная

Хотите склонение слов «день/дня/дней»? Придётся написать свою логику — PHP не умеет склонять существительные. Но это отличное упражнение!

4. Работа с часовыми поясами: когда время имеет значение

Если ваше приложение работает с пользователями из разных часовых поясов, игнорировать временные зоны нельзя. Одна и та же метка времени может означать разное время в Москве и Нью-Йорке.

<?php
$timezone_moscow = new DateTimeZone('Europe/Moscow');
$timezone_ny = new DateTimeZone('America/New_York');

$date_moscow = new DateTime('2024-03-20 15:00:00', $timezone_moscow);
$date_ny = new DateTime('2024-03-20 08:00:00', $timezone_ny);

// Обе даты — одно и то же мгновение!
$interval = $date_moscow->diff($date_ny);
echo "Разница: " . $interval->h . " часов"; // Выведет: 0 часов
?>

Совет: всегда храните даты в UTC в базе данных, а конвертацию в локальный часовой пояс делайте только при отображении пользователю. Это спасёт вас от множества головных болей.

5. Профессиональный уровень: библиотека Carbon

Если вы пишете на Laravel или Symfony, вы наверняка уже встречали Carbon — расширение класса DateTime с невероятно удобным API. Это стандарт де-факто в современном PHP.

Установка через Composer:

composer require nesbot/carbon

А теперь — магия:

<?php
use Carbon\Carbon;

$date1 = Carbon::parse('2024-01-15');
$date2 = Carbon::parse('2024-03-20');

// Разница в днях
echo $date1->diffInDays($date2); // 65

// Разница в часах
echo $date1->diffInHours($date2); // 1560

// Человекочитаемый формат
echo $date1->diffForHumans($date2); // "2 months before"
echo $date2->diffForHumans($date1); // "2 months from now"

// Сравнение
if ($date1->isPast()) {
    echo "Дата в прошлом";
}

if ($date2->isFuture()) {
    echo "Дата в будущем";
}
?>

Carbon предлагает десятки методов: addDays(), subMonths(), startOfDay(), endOfWeek() и многие другие

Блоги

Рекомендаций по книгам