Кастомизация строк вывода

Day.js предоставляет компактный и предсказуемый API для форматирования дат, где основной механизм вывода строк строится вокруг шаблонов формата и подключаемых плагинов. Гибкость системы заключается в том, что каждая строка вывода является результатом применения токенов форматирования, локализации и расширений поведения через плагины.

Основой преобразования даты в строку выступает метод format(), принимающий строку-шаблон. Шаблон состоит из токенов, каждый из которых заменяется соответствующим значением даты.

Наиболее используемые токены:

  • YYYY — полный год (2026)
  • YY — сокращённый год (26)
  • MM — месяц с ведущим нулём (01–12)
  • M — месяц без ведущего нуля (1–12)
  • DD — день месяца (01–31)
  • D — день месяца без ведущего нуля
  • HH — часы в 24-часовом формате
  • mm — минуты
  • ss — секунды

Комбинация токенов формирует итоговую строку:

dayjs().format('YYYY-MM-DD HH:mm:ss')

Такой подход делает форматирование декларативным: структура строки задаётся шаблоном, а библиотека подставляет значения.

Композиция пользовательских форматов

Форматы могут включать любые комбинации токенов и разделителей. Символы, не являющиеся токенами, выводятся как есть:

dayjs().format('DD/MM/YYYY [время:] HH:mm')

Квадратные скобки используются для защиты литералов от интерпретации. Всё внутри [] выводится без изменений. Это особенно важно при создании человекочитаемых шаблонов:

dayjs().format('[Дата создания:] YYYY-MM-DD')

Механизм экранирования позволяет строить сложные строки без необходимости ручной конкатенации.

Экранирование и литералы

Любой символ может быть включён в вывод без риска интерпретации как токена при использовании квадратных скобок. Это фундаментальный элемент системы форматирования.

Пример:

dayjs().format('[YYYY] год')

Выведет строку с буквальным YYYY, а не значением года.

Дополнительно литералы позволяют безопасно комбинировать технические и пользовательские строки:

dayjs().format('[Обновлено:] DD.MM.YYYY [в] HH:mm')

Локализация строк вывода

Форматирование даты тесно связано с локалями. Локаль влияет на названия месяцев, дней недели и правила отображения относительного времени.

При подключении локали меняется поведение форматирования:

import 'dayjs/locale/ru'

dayjs.locale('ru')

После этого:

  • месяцы становятся русскоязычными
  • дни недели отображаются на русском
  • некоторые форматы адаптируются под локальные правила

Однако сам format() остаётся токен-ориентированным, изменяются только текстовые элементы.

Переопределение локали через updateLocale

Для глубокой кастомизации используется updateLocale, позволяющий переопределить правила вывода.

Пример изменения названий месяцев:

dayjs.updateLocale('ru', {
  months: [
    'Янв', 'Фев', 'Мар', 'Апр',
    'Май', 'Июн', 'Июл', 'Авг',
    'Сен', 'Окт', 'Ноя', 'Дек'
  ]
})

Можно модифицировать:

  • полные и короткие названия месяцев
  • дни недели
  • форматы относительного времени
  • правила отображения порядковых чисел

Это превращает локаль в конфигурируемый слой, а не фиксированную сущность.

Форматирование относительного времени

Механизм относительного времени требует подключения плагина relativeTime. Он управляет строками вроде «несколько минут назад» или «через 2 дня».

import relativeTime from 'dayjs/plugin/relativeTime'
dayjs.extend(relativeTime)

После этого:

dayjs().from(dayjs().subtract(2, 'hour'))

Вывод зависит от локали и набора правил.

Кастомизация осуществляется через updateLocale:

dayjs.updateLocale('ru', {
  relativeTime: {
    future: 'через %s',
    past: '%s назад',
    s: 'несколько секунд',
    m: 'минута',
    mm: '%d минут',
    h: 'час',
    hh: '%d часов',
    d: 'день',
    dd: '%d дней',
    M: 'месяц',
    MM: '%d месяцев',
    y: 'год',
    yy: '%d лет'
  }
})

Строки становятся полностью управляемыми, включая грамматические формы.

Календарные строки

Плагин calendar отвечает за форматирование дат относительно текущего времени:

import calendar from 'dayjs/plugin/calendar'
dayjs.extend(calendar)

Пример:

dayjs().calendar()

Выводы вроде «Сегодня в 14:00» или «Завтра в 10:00» зависят от шаблонов календаря, которые также можно переопределять.

Кастомизация:

dayjs.updateLocale('ru', {
  calendar: {
    sameDay: '[Сегодня в] HH:mm',
    nextDay: '[Завтра в] HH:mm',
    lastDay: '[Вчера в] HH:mm',
    sameElse: 'DD.MM.YYYY'
  }
})

Этот слой особенно важен для интерфейсов, где отображается динамическая дата без необходимости ручного форматирования.

Расширенное форматирование через advancedFormat

Плагин advancedFormat добавляет дополнительные токены, расширяющие стандартные возможности:

import advancedFormat from 'dayjs/plugin/advancedFormat'
dayjs.extend(advancedFormat)

Доступные расширенные токены:

  • Do — день месяца с порядковым суффиксом (1st, 2nd и т.д.)
  • Qo — квартал с суффиксом
  • wo — неделя года

Пример:

dayjs().format('Do MMMM YYYY')

Кастомизация порядка и форматов становится более выразительной без усложнения шаблонов.

Создание унифицированного слоя форматирования

В реальных приложениях часто формируется промежуточный слой над format(), который стандартизирует вывод:

const formatDate = (date) => {
  return dayjs(date).format('YYYY-MM-DD')
}

const formatDateTime = (date) => {
  return dayjs(date).format('YYYY-MM-DD HH:mm')
}

Такой подход фиксирует единые правила представления даты и предотвращает расхождение форматов по проекту.

Дополнительно может использоваться конфигурационный объект:

const DATE_FORMATS = {
  short: 'DD.MM.YYYY',
  long: 'DD MMMM YYYY',
  iso: 'YYYY-MM-DD'
}

И применение:

dayjs(date).format(DATE_FORMATS.long)

Особенности композиции строк

При сложных форматах важно учитывать порядок токенов и локализацию. Например, сочетание числовых и текстовых элементов требует контроля за пробелами и литералами:

dayjs().format('DD MMMM YYYY [г.] HH:mm')

Без скобок литералы могут быть интерпретированы неверно, особенно при использовании нестандартных символов.

Типичные ошибки при кастомизации вывода

Одной из частых проблем является попытка использовать JavaScript-строки вместо шаблонов Day.js:

// некорректный подход
dayjs().format(`${year}-${month}-${day}`)

Подобная конструкция нарушает принцип токенизации и приводит к потере гибкости.

Другой проблемой становится смешивание локализованных и ручных строк, что приводит к несогласованности интерфейса.

Также важно учитывать, что updateLocale изменяет глобальное состояние, что может повлиять на другие части приложения.

Управление консистентностью вывода

Для сложных систем форматирования часто выделяется единый модуль, отвечающий за все строки:

  • даты
  • время
  • относительные значения
  • календарные строки

Это позволяет централизованно управлять локалями и шаблонами без дублирования логики.

При масштабировании приложений такой подход обеспечивает стабильность отображения дат и предотвращает рассинхронизацию форматов между компонентами интерфейса.