PHPFlowPHP, MySQL, Laravel и JavaScript

Дата и время в PHP: date(), формат даты, DateTime и часовой пояс

Обновлено:

Коротко

Текущая дата в PHP выводится одной строкой: echo date('d.m.Y H:i');. Для расчётов (прибавить месяц, сравнить даты, посчитать разницу) удобнее объект DateTimeImmutable. Чтобы время совпадало с вашим, задайте часовой пояс: date_default_timezone_set('Europe/Moscow') или date.timezone в php.ini.

Содержание
  1. Текущая дата и время в PHP
  2. Формат даты в date(): основные символы
  3. Часовой пояс: почему время отстаёт на три часа
  4. DateTime и DateTimeImmutable
  5. Разбор даты из строки: createFromFormat
  6. Метка времени: timestamp в дату и обратно
  7. strtotime: относительные даты словами
  8. Сравнение дат в PHP
  9. Разница между датами: diff и DateInterval
  10. Перебор дат по дням и неделям: DatePeriod
  11. День недели и месяц на русском
  12. Время выполнения скрипта
  13. Дата и время в 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
Вывод текущей даты PHP в командной строке с часовым поясом Europe/Moscow и без него
Текущая дата и время в PHP с часовым поясом и без него: без пояса время отстаёт на три часа

Объектный вариант делает то же самое, но результат можно дальше менять и сравнивать:

$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 или 00
UМетка Unix1794742205
cДата в ISO 86012026-11-15T14:30:05+03:00

Буквы D, l, M и F выводят названия дней и месяцев, но только по-английски. Как получить их на русском, показано ниже в разделе про день недели.

Часовой пояс: почему время отстаёт на три часа

Если часовой пояс не задан, PHP считает время по UTC. Для Москвы это разница в три часа, и даты около полуночи "уезжают" на соседний день. Пояс задают одним из способов.

  1. Для всего сервера: откройте php.ini и пропишите date.timezone = Europe/Moscow.
  2. Перезапустите веб-сервер или PHP-FPM.
  3. Проверьте значение командой php -r "echo date_default_timezone_get();".
Директива date.timezone в php.ini
Часовой пояс по умолчанию задаётся в секции [Date] файла php.ini

Где искать нужный 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

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

Пример DateTimeImmutable::createFromFormat с проверкой результата
createFromFormat разбирает дату по заданному шаблону и возвращает false, если строка не подходит

Метка времени: 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
Вывод разницы между датами в PHP
Результат diff(): общее число дней и разбивка на месяцы и дни

Не считайте разницу делением секунд на 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().