Перейти к содержанию

Как отформатировать дату в формате Ydiff (например, «2 года»)

Инструкция
Как вывести разницу между датой и сегодняшним днём словами – «2 года», «6 месяцев», «3 дня». Разбираем относительный формат FormatDate «Ydiff» в Битрикс, автоматическое склонение и как разбить результат на число и слово.

6 мин 53 Обновлено 22 июля Сложность: Базовая

TL;DR

  • FormatDate('Ydiff', MakeTimeStamp($date)) выводит разницу до сейчас: «2 года», «6 месяцев».
  • Третий аргумент FormatDate задаёт точку отсчёта – тогда считается разница между двумя датами.
  • Склонение «год/года/лет» подставляет русская локаль сайта.
  • Результат «2 года» разбивают на число и слово через explode(' ', $diff).
  • Ydiff округляет до одной старшей единицы – «2 года 3 месяца» одной строкой он не даст.

Иногда дату нужно показать не как «01.01.2014», а как прожитый интервал: «Мы на рынке 2 года», «Акция началась 6 месяцев назад». В 1С-Битрикс это делает относительный формат Ydiff функции FormatDate() – он сам вычисляет разницу между датой и текущим моментом и подбирает подходящую единицу измерения со склонением.

Что такое формат Ydiff

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

$first_date = '01.01.2014 00:00:00'; // исходная дата
$diff = FormatDate('Ydiff', MakeTimeStamp($first_date));
echo $diff; // например: 2 года

MakeTimeStamp() переводит строку в Unix-timestamp, а FormatDate('Ydiff', ...) сравнивает его с текущим временем. Третьим аргументом можно передать «точку отсчёта» вместо текущего момента – тогда считается разница между двумя датами:

echo FormatDate('Ydiff', MakeTimeStamp('01.01.2014'), MakeTimeStamp('01.01.2016'));
// 2 года

Как разбить результат на число и слово

Строка «2 года» – это число и единица через пробел. Если их нужно оформить по-разному (крупная цифра и подпись под ней), разбейте результат функцией explode():

$diff = FormatDate('Ydiff', MakeTimeStamp($first_date));
$parts = explode(' ', $diff); // ['2', 'года']

echo '<span class="num">' . $parts[0] . '</span>';   // 2
echo '<span class="unit">' . $parts[1] . '</span>'; // года

Родственные относительные форматы

Кроме Ydiff у FormatDate есть и «человекочитаемые» форматы вроде «X дней назад». Их удобно применять к датам публикаций и комментариев. Логика та же: функция сама выбирает единицу и склонение. Если же нужен обычный «02 июня, 2016», это уже задача буквенных шаблонов – она разобрана в гайде «Сменить формат даты в CMS Битрикс».

Подводные камни

  • Склонение – из локали. Правильные формы «год / года / лет» подставляет русская языковая тема. На английской локали получите «years» – проверьте активный язык сайта.
  • Только целые крупные единицы. Ydiff не покажет «2 года 3 месяца» одной строкой – он округляет до одной старшей единицы. Для составного вывода считайте интервал вручную (например, через DateTime::diff() чистого PHP) и собирайте строку сами.
  • Кэш «замораживает» интервал. Внутри кэшируемого шаблона компонента результат вычисляется в момент генерации кэша и потом не меняется, пока кэш жив. Для точных относительных дат считайте их вне кэша или сбрасывайте кэш по времени.
  • Часовой пояс. MakeTimeStamp трактует строку в часовом поясе сайта. При включённых пользовательских часовых поясах разница у разных посетителей может отличаться на границе суток.
  • Не путайте с датой публикации. Если исходная дата в будущем, «разница до сейчас» будет считаться от будущей точки – для обратного отсчёта до события используйте таймер, а не Ydiff (см. гайды ниже).

Смежные приёмы работы с датами и временем – в гайдах «Сменить формат даты в CMS Битрикс», «Вывод текущего года на PHP», «Счётчик обратного отсчёта в списке новостей» и «Скрипт отсчёта времени до конца акции».

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

Как в Битрикс вывести дату как «2 года» или «6 месяцев»?

Используйте относительный формат FormatDate('Ydiff', MakeTimeStamp($date)). Функция сама вычисляет разницу между датой и текущим моментом и подбирает крупную единицу со склонением.

Можно ли посчитать разницу между двумя произвольными датами?

Да. Передайте вторую дату третьим аргументом: FormatDate('Ydiff', MakeTimeStamp($from), MakeTimeStamp($to)). Тогда точкой отсчёта будет не «сейчас», а $to.

Почему выводится «years» вместо «года»?

Склонение единиц берётся из активной языковой темы. Английский вариант означает, что на сайте активна не русская локализация.

Как показать «2 года 3 месяца» одной строкой?

Формат Ydiff округляет до одной старшей единицы и такой составной вывод не даёт. Для него посчитайте интервал вручную, например через DateTime::diff() чистого PHP, и соберите строку сами.

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

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

Материалы по теме

Что почитать дальше по этой теме

Инструкция Сменить формат даты в CMS «Битрикс» Как вывести поле «Начало активности» элемента инфоблока в формате «02 июня, 2016». Разбираем FormatDate с шаблоном «d F, Y», разбор строки через ParseDateTime и подводные камни с локалью и часовым поясом. 6 мин 49 18 мая 2017 Инструкция Вывод текущего года на PHP (копирайт в подвале) Как автоматически выводить в подвале сайта текущий год или интервал «2022–2026», чтобы копирайт не устаревал 1 января. Разбираем date('Y'), тернарный оператор, часовой пояс и вариант для 1С-Битрикс. 5 мин 68 22 сентября 2022 Инструкция Счётчик обратного отсчёта в «Списке новостей» Битрикса Как вывести ближайшее мероприятие компонентом «Список новостей» и повесить на него таймер обратного отсчёта, взяв дату из свойства элемента. Дату отдаём в JS через data-атрибут, а сам счётчик пишем на чистом JavaScript без jQuery. 8 мин 44 22 октября 2017 Инструкция Скрипт обратного отсчёта времени до конца акции Как поставить на сайт таймер обратного отсчёта до конца акции на чистом JavaScript, без библиотек. Разбираем надёжный разбор даты, счёт от текущего момента, склонение единиц и остановку по нулю. 7 мин 63 18 мая 2017 Инструкция Как вывести определённое поле элемента инфоблока в Битриксе Как в шаблоне компонента 1С-Битрикс вывести одно конкретное поле элемента инфоблока – например счётчик показов SHOW_COUNTER. Разбираем массив FIELDS, служебные поля элемента и безопасный вывод значения. 6 мин 51 18 февраля 2017