Дата и время в PHP: date(), формат даты, DateTime и часовой пояс
Коротко
Текущая дата в PHP выводится одной строкой: echo date('d.m.Y H:i');. Для расчётов (прибавить месяц, сравнить даты, посчитать разницу) удобнее объект DateTimeImmutable. Чтобы время совпадало с вашим, задайте часовой пояс: date_default_timezone_set('Europe/Moscow') или date.timezone в php.ini.
Содержание
- Текущая дата и время в PHP
- Формат даты в date(): основные символы
- Часовой пояс: почему время отстаёт на три часа
- DateTime и DateTimeImmutable
- Разбор даты из строки: createFromFormat
- Метка времени: timestamp в дату и обратно
- strtotime: относительные даты словами
- Сравнение дат в PHP
- Разница между датами: diff и DateInterval
- Перебор дат по дням и неделям: DatePeriod
- День недели и месяц на русском
- Время выполнения скрипта
- Дата и время в MySQL
Текущая дата и время в PHP
Функция date() возвращает строку с датой по шаблону. Без второго аргумента она берёт текущий момент, так что PHP дата "сейчас" выглядит так:
date_default_timezone_set('Europe/Moscow');
echo date('d.m.Y'); // 15.11.2026
echo date('H:i:s'); // 14:30:05
echo date('d.m.Y H:i'); // 15.11.2026 14:30
echo date('Y-m-d H:i:s'); // 2026-11-15 14:30:05, формат для MySQL
echo time(); // метка Unix: число секунд с 01.01.1970

Объектный вариант делает то же самое, но результат можно дальше менять и сравнивать:
$now = new DateTimeImmutable();
echo $now->format('d.m.Y H:i'); // 15.11.2026 14:30
Если нужны миллисекунды, используйте формат v (миллисекунды) или u (микросекунды): $now->format('H:i:s.v'). Функция date() микросекунды не знает и всегда выводит нули.
Формат даты в date(): основные символы
Шаблон в date() и DateTime::format() одинаковый. Каждая буква заменяется частью даты, остальные символы выводятся как есть. Чтобы вывести саму букву, экранируйте её обратным слешем: date('d.m.Y \в H:i').
| Символ | Что выводит | Пример |
|---|---|---|
d / j | День месяца с нулём / без нуля | 05 / 5 |
m / n | Номер месяца с нулём / без нуля | 03 / 3 |
Y / y | Год четырьмя / двумя цифрами | 2026 / 26 |
H / G | Часы 00-23 с нулём / без нуля | 09 / 9 |
i / s | Минуты / секунды | 07 / 45 |
N | День недели: 1 - понедельник, 7 - воскресенье | 7 |
w | День недели: 0 - воскресенье, 6 - суббота | 0 |
t | Количество дней в месяце | 30 |
L | Високосный год: 1 или 0 | 0 |
U | Метка Unix | 1794742205 |
c | Дата в ISO 8601 | 2026-11-15T14:30:05+03:00 |
Буквы D, l, M и F выводят названия дней и месяцев, но только по-английски. Как получить их на русском, показано ниже в разделе про день недели.
Часовой пояс: почему время отстаёт на три часа
Если часовой пояс не задан, PHP считает время по UTC. Для Москвы это разница в три часа, и даты около полуночи "уезжают" на соседний день. Пояс задают одним из способов.
- Для всего сервера: откройте php.ini и пропишите
date.timezone = Europe/Moscow. - Перезапустите веб-сервер или PHP-FPM.
- Проверьте значение командой
php -r "echo date_default_timezone_get();".

Где искать нужный php.ini, рассказано в статье php.ini: где находится и как редактировать. Если доступа к файлу нет, задайте пояс в коде, в общем файле конфигурации проекта:
date_default_timezone_set('Europe/Moscow');
// или пояс только для одного объекта
$utc = new DateTimeImmutable('now', new DateTimeZone('UTC'));
$msk = $utc->setTimezone(new DateTimeZone('Europe/Moscow'));
echo $msk->format('H:i T'); // 14:30 MSK
Хорошая практика: хранить время в базе в UTC, а переводить в пояс пользователя только при выводе. Тогда не будет путаницы, если сервер или посетители окажутся в других регионах.
DateTime и DateTimeImmutable
В PHP два класса для дат. DateTime изменяет сам объект при вызове modify() или add(), а DateTimeImmutable возвращает новый объект и оставляет исходный нетронутым. Второй безопаснее: дата, переданная в функцию, не поменяется у вас за спиной.
$start = new DateTimeImmutable('2026-11-15 10:00');
$tomorrow = $start->modify('+1 day');
$nextMonth = $start->add(new DateInterval('P1M')); // P1M = один месяц
$minus2h = $start->sub(new DateInterval('PT2H')); // PT2H = два часа
echo $start->format('d.m.Y H:i'); // 15.11.2026 10:00, не изменилась
echo $tomorrow->format('d.m.Y'); // 16.11.2026
echo $nextMonth->format('d.m.Y'); // 15.12.2026
Если строку нельзя разобрать, конструктор бросает исключение. С PHP 8.3 это специальный класс DateMalformedStringException, его удобно ловить отдельно:
try {
$date = new DateTimeImmutable($_GET['from'] ?? 'now');
} catch (DateMalformedStringException $e) {
$date = new DateTimeImmutable('today');
}
Разбор даты из строки: createFromFormat
Пользователи пишут даты по-разному, а конструктор понимает не всё. Например, "03.04.2026" он прочитает правильно, а "03/04/2026" примет за 4 марта по американскому порядку. Если формат известен заранее, задайте его явно через createFromFormat():
$input = '15.11.2026 14:30';
$date = DateTimeImmutable::createFromFormat('!d.m.Y H:i', $input);
if ($date === false) {
exit('Неверный формат даты');
}
echo $date->format('Y-m-d H:i:s'); // 2026-11-15 14:30:00
Восклицательный знак в начале шаблона обнуляет поля, которых нет в строке. Без него недостающие секунды или время возьмутся из текущего момента, и сравнение двух "одинаковых" дат неожиданно даст разный результат.

Метка времени: timestamp в дату и обратно
Метка Unix (timestamp) хранит момент времени одним числом. Её отдают многие API, она лежит в старых базах и в filemtime(). Перевод в обе стороны:
$ts = 1794742205;
// timestamp в строку даты
echo date('d.m.Y H:i', $ts);
// timestamp в объект (PHP 8.4+)
$dt = DateTimeImmutable::createFromTimestamp($ts)
->setTimezone(new DateTimeZone('Europe/Moscow'));
// то же для старых версий PHP
$dt = (new DateTimeImmutable())->setTimestamp($ts);
// дата в timestamp
$ts2 = (new DateTimeImmutable('2026-12-31 23:59:59'))->getTimestamp();
$ts3 = strtotime('2026-12-31 23:59:59');
Объект, созданный через new DateTimeImmutable('@' . $ts) или createFromTimestamp(), всегда получает пояс UTC. Чтобы вывести местное время, вызовите setTimezone(), как в примере. Метод createFromTimestamp() появился в PHP 8.4, проверить свою версию можно по инструкции как узнать версию PHP.
strtotime: относительные даты словами
Функция strtotime() переводит английскую фразу в метку времени. Это удобно для "через неделю", "первый день месяца" и подобных вычислений. При ошибке она возвращает false, поэтому результат проверяйте строгим сравнением.
// сегодня 15.11.2026
echo date('d.m.Y', strtotime('+1 week')); // 22.11.2026
echo date('d.m.Y', strtotime('next monday')); // 16.11.2026
echo date('d.m.Y', strtotime('last day of this month')); // 30.11.2026
echo date('d.m.Y', strtotime('first day of next month')); // 01.12.2026
$ts = strtotime('завтра'); // русских слов функция не знает
var_dump($ts); // bool(false)
Те же фразы принимает метод modify(), поэтому в объектном коде отдельный вызов strtotime() не нужен: $date->modify('last day of this month').
Сравнение дат в PHP
Объекты DateTime и DateTimeImmutable сравниваются обычными операторами <, > и ==. Сравниваются моменты времени, даже если у объектов разные часовые пояса.
$deadline = new DateTimeImmutable('2026-11-20 18:00');
$now = new DateTimeImmutable();
if ($now > $deadline) {
echo 'Срок прошёл';
} else {
echo 'Ещё успеваете';
}
// одинаковый ли день, без учёта времени
$a = new DateTimeImmutable('2026-11-15 09:00');
$b = new DateTimeImmutable('2026-11-15 22:40');
var_dump($a->format('Y-m-d') === $b->format('Y-m-d')); // bool(true)
Строки можно сравнивать напрямую только в формате Y-m-d H:i:s: там порядок символов совпадает с порядком дат. Строки вида "15.11.2026" так сравнивать нельзя: "01.12.2026" окажется "меньше" "15.11.2026". Тот же принцип полезно помнить при работе со строками в PHP.
Разница между датами: diff и DateInterval
Метод diff() возвращает объект DateInterval с годами, месяцами, днями и общим числом дней.
$from = new DateTimeImmutable('2026-11-15');
$to = new DateTimeImmutable('2026-12-31');
$diff = $from->diff($to);
echo $diff->days; // 46, всего дней
echo $diff->m . ' мес. ' . $diff->d . ' дн.'; // 1 мес. 16 дн.
echo $diff->format('%a дн.'); // 46 дн.
echo $diff->invert; // 0: вторая дата позже первой
// возраст по дате рождения
$birth = new DateTimeImmutable('1990-05-20');
echo $birth->diff(new DateTimeImmutable('today'))->y; // 36

Не считайте разницу делением секунд на 86400: в дни перевода часов сутки длятся 23 или 25 часов, и результат сдвинется. Свойство days учитывает это само.
Перебор дат по дням и неделям: DatePeriod
Для календаря, графика смен или отчёта по дням нужен список дат подряд. Класс DatePeriod строит его без ручных циклов с прибавлением суток:
$period = new DatePeriod(
new DateTimeImmutable('2026-11-01'),
new DateInterval('P1D'), // шаг: один день
new DateTimeImmutable('2026-11-30'),
DatePeriod::INCLUDE_END_DATE // включить последний день
);
foreach ($period as $day) {
if ((int) $day->format('N') >= 6) {
continue; // пропускаем субботу и воскресенье
}
echo $day->format('d.m'), PHP_EOL;
}
Флаг INCLUDE_END_DATE доступен с PHP 8.2. Шаг можно сделать любым: P1W - неделя, PT30M - полчаса. Последний день месяца без перебора даёт формат t: $date->format('t') вернёт 30 для ноября.
День недели и месяц на русском
Как по дате определить день недели в PHP: формат N даёт номер от 1 до 7, а название берём из своего массива.
$days = [1 => 'понедельник', 'вторник', 'среда', 'четверг',
'пятница', 'суббота', 'воскресенье'];
$date = new DateTimeImmutable('2026-11-15');
echo $days[(int) $date->format('N')]; // воскресенье
// выходной ли день
$isWeekend = (int) $date->format('N') >= 6;
Для полного вывода даты по-русски удобнее расширение intl. Шаблон MMMM даёт месяц в родительном падеже, LLLL в именительном:
$fmt = new IntlDateFormatter(
'ru_RU',
IntlDateFormatter::NONE,
IntlDateFormatter::NONE,
'Europe/Moscow',
null,
'EEEE, d MMMM y'
);
echo $fmt->format(new DateTimeImmutable('2026-11-15')); // воскресенье, 15 ноября 2026
Проверить, включено ли расширение, можно командой php -m: в списке должно быть intl. Функция strftime(), которой раньше выводили русские даты, устарела с PHP 8.1, в новом коде её не используйте.
Время выполнения скрипта
Для замера скорости кода берите hrtime(true): она возвращает наносекунды от монотонного таймера и не зависит от перевода системных часов.
$start = hrtime(true);
// ... код, который замеряем
usleep(150000);
$ms = (hrtime(true) - $start) / 1e6;
printf("Выполнено за %.1f мс\n", $ms); // Выполнено за 150.2 мс
Старый вариант с microtime(true) тоже работает, но даёт секунды с дробной частью и может врать при синхронизации времени на сервере.

Дата и время в MySQL
Столбцы DATE и DATETIME в MySQL принимают строку в формате Y-m-d и Y-m-d H:i:s. Передавайте значение через подготовленный запрос, а при чтении превращайте строку обратно в объект:
$stmt = $pdo->prepare('INSERT INTO orders (user_id, created_at) VALUES (?, ?)');
$stmt->execute([$userId, (new DateTimeImmutable())->format('Y-m-d H:i:s')]);
$row = $pdo->query('SELECT created_at FROM orders ORDER BY id DESC LIMIT 1')->fetch();
$created = new DateTimeImmutable($row['created_at']);
echo $created->format('d.m.Y в H:i');
Подключение к базе и подготовленные запросы подробно разобраны в статье PDO в PHP. Для API даты обычно отдают в формате ISO 8601: $date->format(DATE_ATOM).
Частые вопросы
Как получить текущую дату и время в PHP?
Вызовите date('d.m.Y H:i:s') или (new DateTimeImmutable())->format('d.m.Y H:i:s'). Не забудьте задать часовой пояс, иначе время будет по UTC.
Почему PHP показывает время на 3 часа меньше?
Не задан часовой пояс, и PHP считает время по UTC. Пропишите date.timezone = Europe/Moscow в php.ini или вызовите date_default_timezone_set('Europe/Moscow') в начале скрипта.
Как изменить формат даты в PHP?
Разберите исходную строку через DateTimeImmutable::createFromFormat() и выведите в нужном виде методом format(), например из Y-m-d в d.m.Y.
Как сравнить две даты в PHP?
Создайте два объекта DateTimeImmutable и сравните их операторами <, > или ==. Строки сравнивать можно только в формате Y-m-d H:i:s.
Как узнать день недели по дате в PHP?
Формат N возвращает номер от 1 (понедельник) до 7 (воскресенье): $date->format('N'). Русское название возьмите из своего массива или через IntlDateFormatter.
Как перевести timestamp в дату?
Передайте метку вторым аргументом в date('d.m.Y H:i', $ts). В PHP 8.4 и новее есть DateTimeImmutable::createFromTimestamp($ts), после него задайте пояс через setTimezone().



