Перейти к содержанию
Инструкция

Сменить формат даты в CMS «Битрикс»

Как вывести поле «Начало активности» элемента инфоблока в формате «02 июня, 2016». Разбираем FormatDate с шаблоном «d F, Y», разбор строки через ParseDateTime и подводные камни с локалью и часовым поясом.

Обновлено 22 июля 6 минут чтения 1 просмотр

Дата в Битриксе почти всегда хранится строкой в формате сайта (например, 18.05.2017 00:00:00), а вывести её нужно человеку – «02 июня, 2016», «18 мая» или «Проекту: 6 месяцев». Разберём, как получить любой из этих форматов штатными функциями ядра и не споткнуться на локали и часовом поясе.

Быстрый способ: FormatDate с нужным шаблоном

Проще всего скормить дату функции FormatDate(). Она принимает шаблон и метку времени (Unix timestamp), поэтому исходную строку сначала переводят в timestamp через MakeTimeStamp(). Для формата «02 июня, 2016» подойдёт шаблон d F, Y:

<?= FormatDate('d F, Y', MakeTimeStamp($arItem['ACTIVE_FROM'])) ?>
// 02 июня, 2016

Разберём символы шаблона: d – день с ведущим нулём, F – полное название месяца в родительном падеже («июня», а не «июнь»), Y – год из четырёх цифр. Названия месяцев берутся из активной языковой темы сайта, поэтому вручную склеивать их не нужно – Битрикс сам подставит русские склоняемые формы. Другие полезные символы: j – день без нуля, M – месяц сокращённо, H:i – часы и минуты.

Способ через ParseDateTime, когда нужен контроль над частями

Если дату надо разложить на составляющие (например, вывести день и месяц в разных HTML-блоках), исходную строку разбирают функцией ParseDateTime(). Она возвращает массив с ключами DD, MM, YYYY, HH, MI, SS. Название месяца достают из языкового файла ядра – сообщения MONTH_<N>_S хранят краткую форму в родительном падеже:

<?php foreach ($arResult['FIELDS'] as $code => $value): ?>
    <?php if ($code === 'DATE_ACTIVE_FROM'): ?>
        <div>
            <?php
            $d = ParseDateTime($value, FORMAT_DATETIME);
            echo $d['DD'] . ' '
               . ToLower(GetMessage('MONTH_' . intval($d['MM']) . '_S'))
               . ', ' . $d['YYYY'];
            ?>
        </div>
    <?php endif ?>
<?php endforeach ?>

Здесь intval($d['MM']) убирает ведущий ноль из номера месяца (иначе получится ключ MONTH_06_S, которого нет), а ToLower() приводит название к нижнему регистру. В большинстве случаев этот громоздкий разбор не нужен – его заменяет один вызов FormatDate из первого способа.

Относительные форматы: «Проекту: 6 месяцев»

Кроме буквенных шаблонов у FormatDate есть служебные форматы для относительных дат. Формат Q (он же Ydiff) выводит, сколько времени прошло от указанной даты до текущей – «6 месяцев», «2 года»:

<?= 'Проекту: ' . FormatDate('Q', MakeTimeStamp($arItem['ACTIVE_FROM'])) ?>

Подробный разбор этого формата и его склонений – в отдельном гайде «Как отформатировать дату в формате Ydiff».

Подводные камни: локаль, часовой пояс и кэш

  • Названия месяцев зависят от языковой темы. Если на странице выводится «June» вместо «июня» – проверьте, что активна русская локализация и подключены языковые файлы (MONTH_* есть в русском наборе сообщений ядра). В многоязычном проекте формат меняется вместе с языком.
  • Падеж месяца. Символ F даёт родительный падеж («2 июня»), а сообщение MONTH_N (без суффикса _S) – именительный («Июнь»). Для строки «дата в предложении» нужен именно F / _S.
  • Часовой пояс. MakeTimeStamp трактует строку в часовом поясе сайта. Если на проекте включены пользовательские часовые пояса (модуль главного модуля, автоопределение), время в выводе может «съезжать» – для дат без времени это неважно, но для событий с H:i учитывайте это.
  • Кэш компонента. Форматирование в шаблоне компонента кэшируется вместе с ним. Относительные форматы (Q/Ydiff) внутри кэша «застывают» на момент генерации – их лучше считать вне кэша или сбрасывать кэш по времени.

Смежные приёмы работы с датами – в гайдах «Формат Ydiff (например, 2 года)», «Вывод текущего года на PHP» и «Счётчик обратного отсчёта в списке новостей». Как вывести конкретное поле элемента – см. «Как вывести определённое поле элемента инфоблока».

Частые вопросы

Как вывести дату инфоблока в формате «02 июня, 2016»?

Переведите строку в timestamp и передайте в FormatDate с шаблоном 'd F, Y': FormatDate('d F, Y', MakeTimeStamp($value)). Символ F выводит месяц в родительном падеже, названия берутся из локали сайта.

Чем FormatDate отличается от ParseDateTime?

FormatDate сразу собирает готовую строку по шаблону. ParseDateTime только разбирает дату на массив частей (DD, MM, YYYY, HH, MI, SS) – это удобно, когда день, месяц и год выводятся в разных блоках вёрстки.

Почему вместо «июня» выводится «June»?

Название месяца берётся из активной языковой темы. Английский вариант означает, что активна не русская локализация либо не подключены языковые файлы с сообщениями MONTH_*.

Как получить месяц в именительном падеже – «Июнь» вместо «июня»?

Используйте сообщение MONTH_ без суффикса _S (именительный падеж) или символ шаблона, дающий полное имя без склонения. Символ F и суффикс _S всегда возвращают родительный падеж для конструкций вроде «2 июня».

Почему относительная дата «6 месяцев» не обновляется?

Формат Q (Ydiff) считается в момент генерации шаблона, а результат попадает в кэш компонента и застывает. Считайте относительные форматы вне кэша или настройте сброс кэша по времени.

Валентина Меланина

Хотите обсудить свой проект?

Помогу с разработкой, аналитикой и AI-видимостью вашего сайта

Если у вас есть задача — от внедрения разметки и аналитики до полной переработки сайта — напишите, обсудим объём и подход.