Пользовательские токены

Механизм форматирования дат в Moment.js основан на строке формата, состоящей из предопределённых токенов. Каждый токен представляет собой символическую инструкцию, которая заменяется конкретной частью даты: годом, месяцем, днём, временем или локализованным представлением. Помимо стандартных токенов существует возможность создавать и переопределять поведение форматирования через локаль, что фактически позволяет вводить пользовательские токены на уровне приложения.

Базовая модель токенов форматирования

Встроенные токены Moment.js охватывают все основные компоненты даты:

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

Форматирование выполняется через метод format:

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

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

Локализованные токены как основа пользовательских расширений

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

moment.updateLocale('ru', {
  longDateFormat: {
    LTS: 'HH:mm:ss',
    L: 'DD.MM.YYYY',
    LL: 'D MMMM YYYY',
    LLL: 'D MMMM YYYY HH:mm',
    LLLL: 'dddd, D MMMM YYYY HH:mm'
  }
});

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

moment().format('LLL');

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

Переопределение стандартных форматов через локаль

Переопределение локали позволяет полностью изменить поведение существующих токенов, сохраняя совместимость с вызовом format.

moment.updateLocale('en', {
  longDateFormat: {
    L: 'YYYY/MM/DD',
    LL: 'YYYY MMMM D',
    LLL: 'YYYY MMMM D, HH:mm',
    LLLL: 'dddd YYYY MMMM D HH:mm'
  }
});

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

moment().format('LL');

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

Пользовательские «логические» токены через обёртки

Хотя Moment.js не позволяет регистрировать произвольные токены напрямую, поведение форматирования можно расширить через абстракции на уровне приложения. Создаются именованные функции, возвращающие нужные форматы.

const DATE_FORMATS = {
  short: 'YYYY-MM-DD',
  full: 'dddd, D MMMM YYYY',
  time: 'HH:mm:ss'
};

function formatDate(date, type) {
  return moment(date).format(DATE_FORMATS[type]);
}

В этом случае строковые ключи (short, full, time) фактически выступают пользовательскими токенами верхнего уровня, делегируя работу стандартному механизму Moment.js.

Кастомизация парсинга как обратная сторона токенов

Пользовательские форматы применимы не только к выводу, но и к разбору строк. При использовании moment(input, format) форматная строка определяет, как интерпретируются входные данные.

const customFormat = 'DD**MM**YYYY';

const m = moment('21**05**2026', customFormat);

Система токенов остаётся той же, но позволяет задавать произвольные разделители и структуру входных данных.

Строгий режим усиливает контроль:

moment('21**05**2026', 'DD**MM**YYYY', true).isValid();

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

Внутри локали доступны дополнительные области, которые можно рассматривать как расширенные токены:

  • calendar — форматирование относительных дат
  • relativeTime — правила отображения «через N минут», «N дней назад»
  • ordinal — формат порядковых чисел
moment.updateLocale('ru', {
  calendar: {
    sameDay: '[Сегодня в] LT',
    nextDay: '[Завтра в] LT',
    lastDay: '[Вчера в] LT',
    sameElse: 'L'
  }
});

Здесь строки в квадратных скобках работают как литералы, а LT — как встроенный токен времени. Подобные конструкции образуют гибрид пользовательской логики и стандартных токенов.

Использование литералов для создания псевдотокенов

Moment.js позволяет экранировать части строки форматирования, создавая псевдотокены, которые не интерпретируются движком.

moment().format('[Дата:] YYYY-MM-DD');

Квадратные скобки фиксируют текст, превращая его в постоянный элемент шаблона. Комбинирование литералов и токенов используется для формирования сложных пользовательских шаблонов.

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

Сложные форматы часто строятся через композицию нескольких уровней токенов:

moment.updateLocale('ru', {
  longDateFormat: {
    customReport: 'YYYY [год], MM [месяц], DD [день] — HH:mm'
  }
});
moment().format('customReport');

Такой подход создаёт семантические имена форматов, скрывающие внутреннюю структуру токенов.

Расширение через moment.fn.format

Дополнительный уровень кастомизации достигается через расширение прототипа Moment:

moment.fn.formatByType = function (type) {
  const map = {
    iso: 'YYYY-MM-DDTHH:mm:ss',
    readable: 'DD MMMM YYYY, HH:mm'
  };

  return this.format(map[type]);
};

Теперь объект даты поддерживает собственную систему именованных токенов верхнего уровня.

moment().formatByType('readable');

Ограничения модели пользовательских токенов

Система токенов Moment.js не предусматривает регистрацию новых низкоуровневых символов форматирования. Набор токенов фиксирован, и любое расширение реализуется через:

  • локализацию (updateLocale)
  • обёртки функций
  • композицию строк формата
  • прототипное расширение

Такой дизайн сохраняет стабильность парсера, но переносит гибкость на уровень конфигурации и архитектуры приложения.