Токены форматирования

Форматирование дат в date-fns основано на строках-шаблонах, состоящих из токенов. Каждый токен представляет собой строго определённую часть даты или времени и интерпретируется функцией форматирования при преобразовании объекта Date в строку.

Основной механизм реализуется через функцию:

format(date, formatString)

где formatString — строка, состоящая из комбинации токенов и литерального текста.


Общие принципы работы токенов

Токены в date-fns чувствительны к регистру и строго регламентированы:

  • yyyy и YYYY могут означать разные сущности в разных системах, но в date-fns используется именно yyyy для года
  • MM — месяц, а mm — минуты
  • dd — день месяца
  • HH — часы в 24-часовом формате

Ключевая особенность — отсутствие «магии»: каждый символ имеет фиксированное значение, и любое отклонение от стандарта приводит к интерпретации как обычного текста.


Год

Основные токены года

  • y — сокращённый год (например, 2026 → 26)
  • yy — двухзначный год
  • yyyy — полный год
  • yo — год с порядковым суффиксом (1st, 2nd и т.п. в локализованных форматах)

Примеры:

format(new Date(2026, 0, 15), 'yyyy') // 2026
format(new Date(2026, 0, 15), 'yy')    // 26

Месяцы

Месяцы в date-fns имеют несколько представлений: числовое, текстовое и сокращённое.

  • M — месяц без ведущего нуля (1–12)
  • MM — месяц с ведущим нулём (01–12)
  • MMM — короткое название месяца (Jan, Feb…)
  • MMMM — полное название месяца (January, February…)

Пример:

format(new Date(2026, 0, 15), 'MM')   // 01
format(new Date(2026, 0, 15), 'MMMM') // January

Дни месяца и недели

День месяца

  • d — день месяца (1–31)
  • dd — день месяца с ведущим нулём (01–31)
  • do — день месяца с порядковым суффиксом (1st, 2nd, 3rd)
format(new Date(2026, 0, 3), 'do') // 3rd

День недели

  • E — краткое обозначение дня недели
  • EEE — сокращённое название дня
  • EEEE — полное название дня недели
format(new Date(2026, 0, 15), 'EEEE') // Thursday

Часы, минуты и секунды

Часы

  • H — часы в 24-часовом формате без нуля (0–23)
  • HH — 24-часовой формат с нулём (00–23)
  • h — 12-часовой формат без нуля (1–12)
  • hh — 12-часовой формат с нулём (01–12)
  • a — AM/PM маркер
format(new Date(2026, 0, 15, 9, 5), 'HH:mm') // 09:05
format(new Date(2026, 0, 15, 21, 5), 'hh:mm a') // 09:05 PM

Минуты и секунды

  • m — минуты без нуля (0–59)
  • mm — минуты с нулём
  • s — секунды без нуля
  • ss — секунды с нулём
format(new Date(2026, 0, 15, 10, 3, 7), 'mm:ss') // 03:07

Миллисекунды

  • S — сотые доли секунды
  • SS — десятки миллисекунд
  • SSS — миллисекунды полностью (000–999)
format(new Date(2026, 0, 15, 10, 0, 0, 123), 'SSS') // 123

Кварталы

Кварталы полезны для финансовых и аналитических задач.

  • Q — номер квартала (1–4)
  • QQ — с ведущим нулём
  • Qo — порядковое представление
format(new Date(2026, 4, 1), 'Qo') // 2nd

Порядковые числительные

Токен o используется для преобразования чисел в порядковые формы:

  • do — день месяца с суффиксом
  • Mo — месяц с суффиксом
  • Qo — квартал с суффиксом

Механизм зависит от локали и поддерживает правила языков.


Литералы и экранирование

Любой текст, не являющийся токеном, интерпретируется как строка форматирования. Однако при совпадении с токенами требуется экранирование.

Используются одинарные кавычки:

format(new Date(), "'Today is' yyyy-MM-dd")

Результат:

Today is 2026-05-22

Особенности экранирования

  • текст внутри ' ' не интерпретируется как токены

  • для вставки кавычки используется удвоение:

    "'It''s date'"

Предустановленные форматы

date-fns предоставляет набор готовых шаблонов:

  • P — краткий формат даты
  • PP — средний формат даты
  • PPP — расширенный формат даты
  • PPPP — полный формат даты
  • p — время
  • pp — расширенное время

Пример:

format(new Date(2026, 0, 15), 'PPP')

Эти пресеты зависят от локали и позволяют стандартизировать вывод без ручного составления строк.


Регистрозависимость и ошибки токенов

Токены строго различают регистр:

  • MM — месяц
  • mm — минуты

Ошибочный выбор приводит к некорректному результату без исключения, так как библиотека интерпретирует строку буквально.

Пример типичной ошибки:

format(date, 'yyyy-mm-dd') // mm = минуты, а не месяц

Комбинирование токенов

Форматирование строится через композицию:

format(new Date(2026, 0, 15, 9, 30), 'yyyy-MM-dd HH:mm:ss')

Результат:

2026-01-15 09:30:00

Более сложные шаблоны:

format(
  new Date(2026, 0, 15, 9, 30),
  "EEEE, do 'of' MMMM yyyy, hh:mm a"
)

Локализация токенов

Некоторые токены зависят от локали:

  • названия месяцев (MMMM)
  • дни недели (EEEE)
  • порядковые формы (do, Mo)

Локализация передаётся через объект опций:

format(date, 'PPPP', { locale })

Поведение с недопустимыми токенами

Любой неизвестный фрагмент строки:

  • не вызывает ошибку
  • выводится как обычный текст

Это делает форматирование устойчивым, но требует внимательности при написании шаблонов.


Взаимодействие токенов с Date-объектом

Форматирование не изменяет сам объект Date. Оно лишь читает его компоненты:

  • getFullYear()
  • getMonth()
  • getDate()
  • getHours()
  • getMinutes()
  • getSeconds()

Каждый токен сопоставляется с соответствующим методом извлечения данных.


Составные шаблоны и читаемость

При построении сложных форматов используется структурирование:

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

Пример:

"yyyy-MM-dd 'at' HH:mm:ss"

Частые ошибки при использовании токенов

  • использование YYYY вместо yyyy
  • путаница mm (минуты) и MM (месяцы)
  • отсутствие экранирования текста
  • неправильное использование 12/24-часового формата (hh vs HH)

Эти ошибки приводят к корректному, но неожиданному выводу.


Поведение при работе с временем суток

Различие 12- и 24-часовых форматов критично:

  • HH — сутки 0–23
  • hh — часы 1–12 с AM/PM
format(date, 'HH:mm') // 18:00
format(date, 'hh:mm a') // 06:00 PM