Изоляция тестов

Moment.js — это популярная библиотека для работы с датой и временем в JavaScript, обеспечивающая удобное создание, форматирование и манипуляцию временными значениями. Основной объект библиотеки — moment(), который представляет собой момент времени. Создание объекта может происходить несколькими способами:

const now = moment(); // текущий момент времени
const specificDate = moment("2026-05-22"); // конкретная дата
const fromComponents = moment({ year: 2026, month: 4, day: 22 }); // из компонентов

Важно помнить, что месяцы индексируются с нуля, поэтому май — это 4.

Форматирование даты и времени

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

moment().format("YYYY-MM-DD"); // "2026-05-22"
moment().format("dddd, MMMM Do YYYY, h:mm:ss a"); // "Friday, May 22nd 2026, 3:45:30 pm"

Ключевые символы для форматирования:

  • YYYY — год,
  • MM — месяц с ведущим нулем,
  • DD — день месяца,
  • dddd — полное название дня недели,
  • Do — день с порядковым числом,
  • HH / hh — часы в 24/12-часовом формате,
  • mm — минуты,
  • ss — секунды,
  • a — am/pm.

Манипуляции с датами

Moment.js предоставляет мощные методы для работы с датами:

const date = moment("2026-05-22");
date.add(7, "days"); // добавляет 7 дней
date.subtract(1, "month"); // вычитает 1 месяц

Методы add и subtract принимают числовое значение и единицу времени (years, months, days, hours, minutes, seconds).

Для вычислений разницы между датами используется diff:

const start = moment("2026-05-01");
const end = moment("2026-05-22");
const diffDays = end.diff(start, "days"); // 21

Парсинг и проверка валидности

Для преобразования строк в объекты moment используется встроенный парсер:

const parsed = moment("22-05-2026", "DD-MM-YYYY");

Валидация даты осуществляется с помощью метода isValid():

const invalidDate = moment("31-02-2026", "DD-MM-YYYY");
console.log(invalidDate.isValid()); // false

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

Работа с временными зонами

Moment.js поддерживает работу с временными зонами через Moment Timezone. Пример использования:

const nyTime = moment.tz("2026-05-22 12:00", "America/New_York");
const moscowTime = nyTime.clone().tz("Europe/Moscow");

Ключевой момент — использование clone() для создания независимой копии объекта, чтобы избежать непреднамеренных изменений исходной даты.

Локализация

Moment.js позволяет выводить даты в разных языках с помощью локализации:

moment.locale("ru");
console.log(moment().format("LLLL")); // "пятница, 22 мая 2026 г. 15:45"

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

Изоляция тестов при работе с Moment.js

При написании модульных тестов критически важно изолировать зависимость от текущей даты и времени. Поскольку moment() без аргументов возвращает текущий момент, тесты становятся нестабильными при реальном времени. Для решения применяются методы фиксации времени:

const fixedDate = moment("2026-05-22T12:00:00");

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

const clock = sinon.useFakeTimers(new Date("2026-05-22T12:00:00").getTime());
moment(); // всегда будет возвращать "2026-05-22T12:00:00"
clock.restore(); // восстановление реального времени

Использование клонирования объектов (clone()) позволяет безопасно изменять дату внутри теста, не влияя на другие тесты или глобальные объекты.

const original = moment("2026-05-22");
const modified = original.clone().add(1, "day");
console.log(original.format("YYYY-MM-DD")); // "2026-05-22"
console.log(modified.format("YYYY-MM-DD")); // "2026-05-23"

Работа с периодами и интервалами

Moment.js поддерживает вычисления между моментами с высокой точностью. Для удобного выражения интервалов используется метод duration:

const duration = moment.duration({ days: 5, hours: 12 });
console.log(duration.asHours()); // 132
console.log(duration.humanize()); // "5 дней"

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

Практические рекомендации

  • Использовать фиксацию времени для всех тестов, чтобы избежать нестабильности.
  • Клонировать объекты Moment при любых манипуляциях, чтобы изменения не распространялись на другие участки кода.
  • Форматировать даты через format() только для отображения, а не для внутренних вычислений.
  • Проверять валидность даты после парсинга пользовательских вводов.
  • При работе с зонами времени всегда явно указывать часовой пояс, чтобы избежать ошибок при конвертации.

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