mktime()
Функция PHP mktime(): порядок аргументов, нормализация дат, поведение часовых поясов и когда лучше использовать классы DateTime.
Функция PHP mktime() строит Unix-временную метку из отдельных частей даты и времени — часа, минуты, секунды, месяца, дня и года. Она является обратной к date(): если date() преобразует временную метку в форматированную строку, то mktime() преобразует части даты в метку, которую можно хранить, сравнивать или использовать в арифметических операциях.
В этой главе рассматривается порядок аргументов (который сбивает с толку почти всех), автоматическая нормализация выходящих за пределы значений, поведение часовых поясов и ситуации, когда лучше обратиться к классам DateTime.
Синтаксис
mktime(
int $hour = (current hour),
?int $minute = (current minute),
?int $second = (current second),
?int $month = (current month),
?int $day = (current day),
?int $year = (current year)
): int|falseПервый аргумент $hour является обязательным начиная с PHP 8.0 — вызов mktime() без аргументов выбрасывает ArgumentCountError. Любой пропущенный аргумент по умолчанию принимает значение соответствующей части текущей локальной даты и времени. Функция возвращает временную метку в виде целого числа или false, если аргументы задают дату за пределами допустимого диапазона.
Unix-временная метка — это количество секунд, прошедших с эпохи Unix — 1 января 1970 года, 00:00:00 UTC. Это универсальный способ представления дат в PHP, базах данных и операционных системах.
Обратите внимание на порядок аргументов.
mktime()принимает время до даты:hour, minute, second, month, day, year. Это отличается от привычного способа записи дат (год-месяц-день), что является наиболее частым источником ошибок.
Создание конкретной временной метки
Чтобы представить фиксированный момент времени, передайте все шесть частей. Здесь мы строим 14:30 15 июня 2024 года:
Мы явно задаём часовой пояс, чтобы результат был воспроизводимым. Без date_default_timezone_set() функция mktime() интерпретирует части даты в часовом поясе, настроенном на сервере, что может сместить итоговую временную метку.
Арифметика дат с mktime()
Поскольку временная метка — это просто количество секунд, можно прибавлять или вычитать секунды, чтобы перемещаться вперёд или назад во времени. Чтобы найти дату через 30 дней от заданной, добавьте 30 × 86400 секунд (в сутках 86 400 секунд):
Прибавление 30 дней к дате
Такой подход с сырыми секундами подходит для целых дней, но игнорирует переходы на летнее время: «день» не всегда равен ровно 86 400 секундам. Для корректной календарной арифметики при переходах через границы летнего/зимнего времени используйте DateTime::modify() или DateInterval.
Автоматическая нормализация
Удобная особенность mktime() состоит в том, что функция нормализует выходящие за пределы значения: вместо ошибки она переводит их в корректную дату. Передайте месяц 13 — получите январь следующего года; передайте день 0 — получите последний день предыдущего месяца:
Это делает mktime() удобной для вычислений вида «последний день месяца»: mktime(0, 0, 0, $month + 1, 0, $year) возвращает последний день $month. Однако такая гибкость означает, что mktime() не отвергает явно недопустимые даты, например 30 февраля — она молча нормализует их. Если вам нужно проверить корректность календарной даты, используйте сначала checkdate().
Распространённые ошибки
- Неправильный порядок аргументов. Запись
mktime(2024, 6, 15)в расчёте на год-месяц-день даёт бессмысленную дату. Помните: сначала время, затем месяц, день, год. - Нет аргументов в PHP 8. Вызов
mktime()без аргументов выбрасываетArgumentCountError. Для получения текущей временной метки используйтеtime(). - Двузначные годы. Передавайте полный четырёхзначный год. Значения
0–69отображаются на 2000–2069, а70–100— на 1970–2000, что редко соответствует ожиданиям.
mktime() и классы DateTime
mktime() является процедурной функцией и работает в локальном часовом поясе. Для UTC-значений используйте её аналог gmmktime(). В новом коде предпочтительнее объектно-ориентированные классы DateTime и DateTimeImmutable — они хранят информацию о часовом поясе, корректно обрабатывают арифметику с учётом летнего времени и позволяют избежать ручных вычислений в секундах:
Заключение
mktime() строит Unix-временную метку из частей даты и времени, автоматически нормализуя выходящие за пределы значения — что делает её удобной для быстрой арифметики дат и трюков вроде «последнего дня месяца». Помните об особенностях: время идёт перед датой в списке аргументов, а вызов без аргументов теперь вызывает ошибку (используйте time() для получения текущего момента). Для работы с учётом летнего времени и часовых поясов в современном PHP обращайтесь к DateTimeImmutable и DateInterval. Смотрите также checkdate() для валидации и strtotime() для разбора дат из строк в человекочитаемом формате.