Условное форматирование

Условное форматирование в Moment.js основано на выборе способа отображения даты или времени в зависимости от контекста: расстояния до текущего момента, диапазона значений, локали и заранее заданных правил. В отличие от статического format(), где строка вывода всегда фиксирована, здесь применяется логика, изменяющая представление данных динамически.

Основные механизмы, обеспечивающие условное форматирование в Moment.js:

  • относительное время (fromNow, toNow)
  • календарное форматирование (calendar)
  • локализованные правила отображения
  • ручная логика через diff и условия в коде
  • настройка порогов отображения

Базовое форматирование и его ограничения

Метод format() формирует строку даты по шаблону токенов:

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

Этот подход не учитывает контекст. Например, одинаковый формат применяется к:

  • текущему времени
  • вчерашней дате
  • событию годичной давности

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


Относительное время как форма условного форматирования

Методы fromNow() и toNow() формируют строку на основе разницы между датами и текущим временем.

moment().subtract(5, 'minutes').fromNow(); // "5 минут назад"
moment().add(2, 'days').fromNow();         // "через 2 дня"

Внутренняя логика выбирает единицы измерения автоматически:

  • секунды
  • минуты
  • часы
  • дни
  • месяцы
  • годы

Алгоритм основан на вычислении разницы и выборе наиболее подходящего диапазона.


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

Moment.js позволяет изменять чувствительность отображения через relativeTimeThreshold.

moment.relativeTimeThreshold('m', 45);
moment.relativeTimeThreshold('h', 22);
moment.relativeTimeThreshold('d', 26);

Эти параметры влияют на момент переключения между единицами измерения.

Пример влияния:

  • 44 минуты → “44 минуты назад”
  • 45 минут → “час назад” (при заданном пороге)

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


Календарное форматирование как расширенное условное отображение

Метод calendar() использует набор правил, определяющих формат в зависимости от разницы между датами.

moment().calendar();

Стандартное поведение включает категории:

  • сегодня
  • вчера
  • завтра
  • в пределах недели
  • более старые даты

Пример результата:

  • “Сегодня в 14:00”
  • “Вчера в 18:30”
  • “10.03.2026”

Настройка правил calendar()

Поведение можно полностью переопределить через updateLocale.

moment.updateLocale('ru', {
  calendar: {
    sameDay: '[Сегодня в] LT',
    nextDay: '[Завтра в] LT',
    nextWeek: 'dddd [в] LT',
    lastDay: '[Вчера в] LT',
    lastWeek: 'DD.MM.YYYY',
    sameElse: 'DD.MM.YYYY'
  }
});

Каждое правило соответствует условию:

  • sameDay — текущий день
  • nextDay — следующий день
  • nextWeek — ближайшая неделя
  • lastDay — вчера
  • lastWeek — прошлая неделя
  • sameElse — все остальные случаи

Фактически это декларативная система условного форматирования.


Использование diff для ручного условного форматирования

Метод diff() возвращает разницу между датами в заданных единицах измерения.

const a = moment('2026-05-21');
const b = moment('2026-05-18');

a.diff(b, 'days'); // 3

На основе результата формируются условия отображения:

const date = moment('2026-05-21');
const now = moment();

if (date.diff(now, 'days') === 0) {
  date.format('[Сегодня]');
} else if (date.diff(now, 'days') === -1) {
  date.format('[Вчера]');
} else {
  date.format('YYYY-MM-DD');
}

Такой подход позволяет реализовать полностью кастомную логику, выходящую за рамки встроенных методов Moment.js.


Комбинирование format и условий

Условное форматирование часто реализуется через комбинирование format() и логических проверок.

const date = moment('2026-05-21');

const output =
  date.isSame(moment(), 'day')
    ? date.format('[Сегодня в] HH:mm')
    : date.isBefore(moment(), 'day')
      ? date.format('[Прошедшая дата:] DD.MM.YYYY')
      : date.format('DD.MM.YYYY');

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

  • isSame
  • isBefore
  • isAfter
  • isBetween

Локализация как фактор условного форматирования

Moment.js поддерживает локали, которые влияют на правила вывода текста, месяцев, дней недели и относительных выражений.

moment.locale('ru');
moment().fromNow();

Каждая локаль содержит:

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

Это означает, что один и тот же код может формировать разные строки в зависимости от активной локали.


Изменение правил relativeTime

Локаль также содержит настройки relativeTime, определяющие строки для каждого диапазона.

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

Эта система формирует основу условного вывода в fromNow().


Гибридные схемы условного форматирования

В реальных сценариях часто применяется комбинированный подход:

  • calendar() для ближайших дат
  • fromNow() для событий в прошлом и будущем
  • format() для исторических записей
const date = moment('2026-05-20');
const now = moment();

let output;

if (date.diff(now, 'days') === 0) {
  output = date.calendar();
} else if (Math.abs(date.diff(now, 'days')) < 7) {
  output = date.fromNow();
} else {
  output = date.format('DD.MM.YYYY');
}

Такая схема позволяет разделять временные интервалы на смысловые категории.


Использование isValid в условном форматировании

Некорректные даты требуют отдельной обработки.

const date = moment('invalid-date');

if (!date.isValid()) {
  date.format('[Некорректная дата]');
}

Метод isValid() предотвращает распространение ошибок в форматировании и позволяет подставлять резервные значения.


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

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

const duration = moment.duration(90, 'minutes');

if (duration.asMinutes() < 60) {
  // минуты
} else if (duration.asHours() < 24) {
  // часы
} else {
  // дни
}

Методы:

  • asSeconds
  • asMinutes
  • asHours
  • asDays

дают числовую основу для условной логики.


Поведение при переходах границ единиц измерения

Moment.js автоматически изменяет представление при переходе через пороги:

  • 59 секунд → “59 секунд назад”
  • 60 секунд → “минуту назад”
  • 59 минут → “59 минут назад”
  • 60 минут → “час назад”

Эти переходы зависят от внутренней логики округления и настроек локали.


Кастомные стратегии отображения временных данных

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

function formatDate(date) {
  const m = moment(date);
  const now = moment();

  if (m.isSame(now, 'minute')) return m.format('[Сейчас]');
  if (m.isSame(now, 'day')) return m.calendar();
  if (m.isSame(now, 'year')) return m.format('DD MMM');
  return m.format('DD.MM.YYYY');
}

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


Приоритеты правил форматирования

При разработке логики отображения учитываются приоритеты:

  1. Валидность даты
  2. Близость к текущему времени
  3. Принадлежность к диапазону (день, неделя, год)
  4. Глобальные правила локали
  5. Резервный формат

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