JUNIOR-BLOG

Для всех кто увлекается программированием

Главная

Работа с датами в PHP

1. DateTime vs DateTimeImmutable

   ✅ DateTime

  • Изменяемый объект
  • Методы, такие как modify() и add(), меняют исходный объект
$date = new DateTime('2020-01-01');
$date->modify('+1 day');
echo $date->format('Y-m-d'); // 2020-01-02

  ✅ DateTimeImmutable

  • Неизменяемый объект
  • Все изменения возвращают новый объект, старый остаётся прежним
$date = new DateTimeImmutable('2020-01-01');
$newDate = $date->modify('+1 day');
echo $date->format('Y-m-d');     // 2020-01-01
echo $newDate->format('Y-m-d');  // 2020-01-02

2. DateTimeInterface

Это интерфейс, реализуемый DateTime и DateTimeImmutable.

✅ Используйте его в типизации методов, чтобы не привязываться к конкретной реализации:

function formatDate(\DateTimeInterface $date): string {
    return $date->format('Y-m-d');
}

3. Частые манипуляции с датами

modify()

$date = new DateTimeImmutable('2024-05-01');
$nextMonth = $date->modify('+1 month'); // 2024-06-01

diff()

$birth = new DateTime('2000-01-01');
$now = new DateTime();
$age = $birth->diff($now)->y; // Получить возраст

📆 add() и sub()

$date = new DateTimeImmutable('2024-01-01');
$interval = new DateInterval('P10D'); // 10 дней

$newDate = $date->add($interval); // 2024-01-11

🔁 Сравнение дат

if ($date1 > $date2) {
    echo 'date1 позже date2';
}

4. 🧮 DateInterval: Что это и зачем нужен?

DateInterval — это объект, представляющий интервал (разницу) между датами или "отрезок времени", который можно добавить/отнять от даты.

$interval = new DateInterval('P10D'); // 10 дней
$date->add($interval); // прибавит 10 дней
$date->sub($interval); // отнимет 10 дней

Формат ISO 8601:

  • P — "Period"
  • T — перед временем (Time)
  • P1Y2M3DT4H5M6S — 1 год, 2 мес., 3 дня, 4 часа, 5 минут, 6 сек
$interval = new DateInterval('P1Y2M'); // 1 год и 2 месяца

Пример: выдать документ, действующий 14 дней

$issuedAt = new DateTimeImmutable();
$validUntil = $issuedAt->add(new DateInterval('P14D'));

 

5. Полезные методы

 

МетодНазначение
format('Y-m-d')Строковое представление
setTime(h, m, s)Установка времени
setDate(y, m, d)Установка даты
getTimestamp()UNIX timestamp
createFromFormat()Создание из произвольного формата

 

6. Работа с временными зонами

$tz = new DateTimeZone('Europe/Moscow');
$now = new DateTime('now', $tz);

6. Примеры из практики

✅ Проверка возраста 20 лет

function isAfterTwentyYears(DateTimeInterface $birthDate, DateTimeInterface $issuedDate): bool {
    $twentyYears = (new DateTimeImmutable($birthDate->format('Y-m-d')))->modify('+20 years');
    return $issuedDate >= $twentyYears;
}

 

✅ Получить возраст в годах

function getAge(DateTimeInterface $birthDate): int {
    return $birthDate->diff(new DateTimeImmutable())->y;
}

 

✅ Обрезать дату до начала дня (00:00:00)

function startOfDay(DateTimeInterface $date): DateTimeImmutable {
    return (new DateTimeImmutable($date->format('Y-m-d')))->setTime(0, 0);
}

7. Не хардкоди now — прокидывай текущую дату зависимостью

Это ключевая практика для тестируемости и гибкости:

❌ Плохо:

 

if ($someDate < new DateTimeImmutable()) {
    ...
} 

✅ Хорошо:

function isExpired(DateTimeInterface $checkDate, DateTimeInterface $now): bool {
    return $checkDate < $now;
}

8. Рекомендации и best practices

  • ✅ Используй DateTimeImmutable по умолчанию — это безопаснее и предсказуемо
  • ✅ Типизируй параметры через DateTimeInterface
  • ✅ Используй DateInterval для работы с интервалами
  • ✅ Сохраняй даты в UTC и показывай пользователю с учётом временной зоны
  • ✅ Не хардкоди now — прокидывай текущую дату в зависимости

🎁 Бонус: Класс-помощник

class DateHelper
{
    public static function addDays(DateTimeInterface $date, int $days): DateTimeImmutable
    {
        return (new DateTimeImmutable($date->format('Y-m-d')))->modify("+{$days} days");
    }

    public static function isExpired(DateTimeInterface $date): bool
    {
        return $date < new DateTimeImmutable();
    }

    public static function formatIso(DateTimeInterface $date): string
    {
        return $date->format(DateTime::ATOM);
    }
}

 

 

Работа с датами в PHP может быть простой и безопасной, если использовать DateTimeImmutable, правильно типизировать методы и применять стандартные инструменты. Это повышает читаемость кода, избавляет от багов и облегчает тестирование.

Итоги

  • Все методы DateTime работают также с DateTimeImmutable.
  • Главное отличие: DateTimeImmutable не изменяет объект, а создаёт новый, в то время как DateTime изменяет сам объект.
  • Оба класса реализуют интерфейс DateTimeInterface, что позволяет использовать их в одном контексте и передавать в функции с типизацией через этот интерфейс.

Используя DateTimeImmutable, вы избегаете случайных побочных эффектов, что делает код более предсказуемым и безопасным.

Похожие статьи

Что такое Ngrok и как им пользоваться при разработке Telegram-бота

Как с помощью ngrok быстро настроить локальную разработку Telegram-бота с вебхуками, получить публичный HTTPS-адрес и протестировать бота без настройки хостинга и открытия портов.

Читать дальше...

Комментарии