IntlDateFormatter выводит дату не на том языке

  • Обновлено
  • Чтение ≈ 4 минуты

Краткий ответ

IntlDateFormatter использует ICU, а не просто системную локаль оболочки. Значения locale, timezone, calendar и pattern при создании форматтера влияют на конечный текст независимо от языка страницы HTML.

В этой статье
  1. Симптомы, область применения и причины
  2. Безопасная диагностика и пошаговое исправление
  3. Как проверить результат и что делать дальше

#Симптомы, область применения и причины

PHP IntlDateFormatter выводит месяцы и дни недели на другом языке после переноса или обновления сервера. Как проверить переданную локаль, часовой пояс, шаблон и версию ICU. IntlDateFormatter использует ICU, а не просто системную локаль оболочки. Значения locale, timezone, calendar и pattern при создании форматтера влияют на конечный текст независимо от языка страницы HTML.

Возможная причинаКак узнатьЧто делать
Локаль не задана явноВ конструкторе используется значение по умолчанию, зависящее от окружения приложения.Один сервер показывает английские месяцы, другой русские.Передать ожидаемую локаль явно, например ru_RU.
Шаблон или часовой пояс формируют неожиданную датуВ функции вручную указаны поля или зона, отличающаяся от настроек проекта.Язык верен, но дата сдвинута на день либо используется неподходящая форма месяца.Проверить timezone и соответствующий стиль/шаблон.
Версии ICU отличаютсяСведения CLDR и склонения названий месяцев могут меняться между версиями ICU.После обновления сервера появилась другая формулировка при тех же параметрах.Сравнить значения Intl и зафиксировать требуемое представление тестом.

#Безопасная диагностика и пошаговое исправление

  1. Сохраните реальный пример неверной датыОткройте страницу, где видна проблема, и запишите исходную дату-время, ожидаемое значение на русском и фактически выведенный текст. Отдельно отметьте, неверны ли только слова или ещё и календарный день. Не делайте вывод о сломанной локали, если проблема лишь в переносе времени через полночь: это, скорее всего, часовой пояс.
  1. Найдите место создания форматтераВ редакторе кода выполните поиск по new IntlDateFormatter( и datefmt_create(. Просмотрите аргументы: locale, тип даты, тип времени, timezone, calendar и при наличии pattern. Если локаль получена из HTTP-заголовка пользователя, проверьте её допустимость и ожидаемое значение для тестового запроса. Не подменяйте язык приложения глобальной сменой параметров ОС.
  1. Проверьте расширение Intl именно для сайтаВ панели параметров PHP убедитесь, что расширение intl включено для версии PHP, обслуживающей сайт. В терминале можно выполнить php -m для CLI и найти intl, но этот результат не описывает другие версии PHP-FPM. Если в браузере есть Class "IntlDateFormatter" not found, это уже отсутствие расширения, а не ошибка локали; попросите администратора подключить совместимый модуль через панель.
  2. По SSH в терминале Linux, обычные права
    Linux · Терминал (Bash)Команда
    По SSH в терминале Linux, обычные права. Список модулей относится только к PHP командной строки.
    php -m
  1. Задайте локаль и часовой пояс явно в диагностическом примереВ тестовой копии приложения вызовите IntlDateFormatter с явными параметрами ru_RU и Europe/Moscow либо актуальной зоной вашего проекта. Не копируйте чужой часовой пояс в рабочий код без сопоставления требований сайта. Используйте фиксированную дату, чтобы сравнить результат с двумя серверами при одинаковом входе.
  2. Пример кода по теме
    PHP
    Только тестовый пример; для своего проекта замените часовой пояс на требуемый, а вывод не оставляйте публичным диагностическим маршрутом.
    <?php
    $dt = new DateTimeImmutable('2026-01-15 12:00:00', new DateTimeZone('Europe/Moscow'));
    $fmt = new IntlDateFormatter('ru_RU', IntlDateFormatter::LONG, IntlDateFormatter::NONE,
        'Europe/Moscow', IntlDateFormatter::GREGORIAN);
    echo $fmt->format($dt);
  1. Разделите локаль и параметры шаблонаЕсли простой пример правильно показывает русский месяц, вернитесь к шаблону реальной страницы. У setPattern и аргумента pattern правила ICU; буквальные части и различия контекста месяца (MMMM/LLLL) меняют форму слова. Для отображения в русском падежах не пытайтесь исправлять результат перебором системных переменных; выберите подходящий шаблон и проверьте ожидаемое грамматическое употребление.
  1. Сопоставьте ICU, PHP и часовую зону разных серверовВ тестовом журнале приложения запросите INTL_ICU_VERSION, IntlDateFormatter::getLocale() и date_default_timezone_get(). Не публикуйте полный phpinfo() в интернете. Если ICU отличается, изменения в лингвистических данных возможны и не обязательно являются ошибкой; для точного текста страницы лучше покрыть форматирование тестом. При разных датах независимо проверьте источник UNIX-времени и timezone.
  2. Исполнять после создания переменной $fmt в защищённом тестовом маршруте
    PHP
    Исполнять после создания переменной $fmt в защищённом тестовом маршруте. После проверки убрать журналирование.
    <?php
    error_log('ICU='.INTL_ICU_VERSION);
    error_log('PHP timezone='.date_default_timezone_get());
    error_log('formatter locale='.$fmt->getLocale());
  1. Исправьте код с возможностью откатаВнесите явную локаль и пояс или скорректируйте шаблон в одном месте проекта. Сохраните предыдущую версию файла и набор контрольных дат (первое число месяца, конец года, дата около полуночи). Прогоните тесты, затем разверните обновление штатным способом. Не меняйте locale для всех пользователей, если сайт многоязычный.
  1. Проверьте результат на двух датах и двух языкахДля русского интерфейса убедитесь, что месяцы отображаются по-русски и день не смещён. Если сайт многоязычный, повторите для английского или другого поддерживаемого языка и проверьте, что изменение не затронуло его. При неуспехе верните прежний файл из копии и приложите к заявке значения locale, timezone, ICU и исходные контрольные даты.

#Как проверить результат и что делать дальше

Успех — одинаковый исходный момент времени даёт ожидаемые дату, язык и форму месяца на целевой версии PHP/ICU без нарушения других локалей. Если видите другой день, продолжайте диагностику часового пояса отдельно от перевода.

Так эту ошибку тоже называют

Источники и обновления

Последнее обновление статьи: 2 ноября 2026. Версии программ и интерфейсы меняются — если шаги не совпадают с вашей версией, сверяйтесь с документацией производителя.