W3docs

PHP Date

Функции даты в PHP необходимы для работы с датами и временем. В этом руководстве мы рассмотрим основные инструменты и классы.

Введение

Почти каждое приложение должно читать, форматировать даты или выполнять с ними арифметические операции: записи в журналах, метки «опубликовано 3 дня назад», планирование, проверка сроков действия. PHP предоставляет два параллельных инструментария:

  • Процедурные функции, построенные на основе Unix-метки времени — целого числа, отсчитывающего секунды с 1 января 1970 года, 00:00:00 UTC. Сюда относятся time(), date(), strtotime() и mktime().
  • Объектно-ориентированный API DateTimeDateTime, DateTimeImmutable, DateTimeZone и DateInterval — который безопаснее для арифметики и работы с часовыми поясами.

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

Заметка о часовых поясах

По умолчанию PHP использует часовой пояс, настроенный в php.ini (параметр date.timezone). Если он не задан, результаты могут различаться на разных серверах. Устанавливайте его явно в начале скрипта или передавайте DateTimeZone каждому объекту:

date_default_timezone_set('UTC');

См. Часовые пояса PHP для полного списка допустимых идентификаторов и информации о преобразовании между поясами.

Функция date()

date(string $format, ?int $timestamp = null) форматирует метку времени в строку, удобную для чтения. Если метку времени не указать, используется текущее время. Это основной инструмент для отображения дат.

echo date('Y-m-d H:i:s'); // e.g. 2023-10-25 14:30:00
echo date('l, F j, Y');   // e.g. Wednesday, October 25, 2023

Строка format состоит из символов-заполнителей. Наиболее употребительные из них:

СимволЗначениеПример
Y4-значный год2023
mМесяц с ведущим нулём10
dДень месяца с ведущим нулём25
HЧас в 24-часовом формате с ведущим нулём14
iМинуты с ведущим нулём30
sСекунды с ведущим нулём00
lПолное название дня неделиWednesday
FПолное название месяцаOctober

Чтобы вывести букву, которая также является символом формата, экранируйте её обратным слешем: date('\T\o\d\a\y: Y-m-d').

Функция time()

time() возвращает текущую Unix-метку времени в виде целого числа. Используйте её всякий раз, когда нужно числовое «сейчас» для хранения, сравнения или арифметики.

$now = time();
echo $now; // an integer such as 1698241800

// One hour from now:
echo date('Y-m-d H:i:s', $now + 3600);

Поскольку метка времени — это просто целое число секунд, к ней можно напрямую прибавлять или вычитать промежутки времени (+ 3600 для часа, + 86400 для дня). Для чего-либо сложнее нескольких фиксированных смещений предпочтительнее использовать арифметику DateTime, описанную ниже.

Функция strtotime()

strtotime(string $datetime, ?int $baseTimestamp = null) разбирает текстовую запись даты/времени на английском языке в метку времени, возвращая false при ошибке. Функция понимает как абсолютные строки, так и относительные фразы.

echo strtotime('2023-10-25 14:30:00'); // 1698244200 (UTC)
echo "\n";
var_dump(strtotime('next monday'));    // a future timestamp, or false if unparseable
$tomorrow = strtotime('+1 day');
echo date('Y-m-d', $tomorrow);

Всегда проверяйте на false перед использованием результата, поскольку опечатка приводит к тихому сбою, а не к исключению.

Функция mktime()

mktime(int $hour, int $minute, int $second, int $month, int $day, int $year) создаёт метку времени из отдельных компонентов. Обратите внимание, что аргументы передаются сначала для времени, затем для даты.

$timestamp = mktime(0, 0, 0, 12, 31, 2023);
echo date('Y-m-d', $timestamp); // 2023-12-31

mktime() нормализует значения за пределами допустимого диапазона, что удобно: mktime(0, 0, 0, 13, 1, 2023) преобразует «13-й месяц» в январь 2024 года.

Класс DateTime

new DateTime(string $datetime = 'now', ?DateTimeZone $timezone = null) оборачивает дату в объект, который можно форматировать, сравнивать и изменять с помощью вызовов методов. (Функция date_create() является процедурным псевдонимом того же конструктора.)

$date = new DateTime('2023-10-25', new DateTimeZone('UTC'));
echo $date->format('Y-m-d'); // 2023-10-25

DateTime является изменяемым — методы вроде modify() изменяют объект на месте. Это источник незаметных ошибок при совместном использовании объекта, поэтому обычно предпочтительнее иммутабельная версия, описанная ниже.

Класс DateTimeImmutable

DateTimeImmutable имеет тот же API, что и DateTime, но каждый изменяющий метод возвращает новый объект, оставляя оригинал нетронутым. Для современного кода это более безопасный вариант по умолчанию.

$date = new DateTimeImmutable('2023-10-25');
$newDate = $date->modify('+1 day');
echo $date->format('Y-m-d');    // 2023-10-25 (unchanged)
echo "\n";
echo $newDate->format('Y-m-d'); // 2023-10-26

Метод DateTime::format()

format(string $format) преобразует объект DateTime или DateTimeImmutable в строку. Он принимает те же символы формата, что и функция date().

$date = new DateTimeImmutable('2023-10-25 14:30:00');
echo $date->format('l, F j, Y'); // Wednesday, October 25, 2023

Арифметика дат и разница между датами

Объектный API отлично подходит для арифметики. Используйте DateInterval (строки длительности ISO-8601) для прибавления или вычитания, и diff() для сравнения двух дат:

$start = new DateTimeImmutable('2023-10-25');
$later = $start->add(new DateInterval('P10D')); // P10D = 10 days
echo $later->format('Y-m-d'); // 2023-11-04

$diff = $start->diff(new DateTimeImmutable('2023-12-31'));
echo "\n" . $diff->days . ' days apart'; // 67 days apart

Выбор подходящего инструмента

  • Нужно быстро отформатировать «сейчас»? Используйте date().
  • Храните или сравниваете момент в числовом виде? Используйте time() / Unix-метки времени.
  • Разбираете пользовательский или журнальный ввод? Используйте strtotime() (и проверяйте на false).
  • Выполняете арифметику, вычисляете разницы или конвертируете часовые пояса? Используйте DateTimeImmutable с DateInterval.

Типичные ошибки

  • Незаданный часовой пояс. Без date_default_timezone_set() или значения в php.ini результаты зависят от сервера. Устанавливайте его один раз в самом начале.
  • strtotime() возвращает false для нераспознанных строк — функция никогда не генерирует исключение, поэтому всегда выполняйте проверку.
  • DateTime является изменяемым. modify() мутирует оригинал; используйте DateTimeImmutable, чтобы избежать проблем с разделяемым состоянием.
  • Метки времени — это секунды UTC. При форматировании через date() применяется текущий часовой пояс, поэтому одно и то же целое число отображается по-разному в зависимости от настроек.

Заключение

PHP предоставляет процедурный инструментарий для работы с метками времени (date(), time(), strtotime(), mktime()) и объектно-ориентированный (DateTime, DateTimeImmutable). Полагайтесь на обычные метки времени для простого отображения и хранения, а на DateTimeImmutable — для арифметики и логики с учётом часовых поясов. Для более детального изучения см. Дата и время в PHP, справочник date(), strtotime() и mktime().

Практика

Практика
Что делает функция 'date' в PHP?
Что делает функция 'date' в PHP?
Was this page helpful?