При работе с Moment.js ключевой аспект устойчивости приложения заключается в корректной валидации создаваемых объектов момента времени. Любая операция с датой — парсинг строки, арифметика времени, преобразование форматов — может привести к появлению невалидного состояния, которое при отсутствии проверки распространяется по цепочке вычислений и даёт трудноуловимые ошибки.
Каждый объект Moment после создания содержит внутренний флаг валидности. Он определяет, был ли успешно разобран входной формат и соответствует ли полученное значение корректной календарной дате.
Основной инструмент проверки — метод isValid():
const m1 = moment("2025-12-01");
console.log(m1.isValid()); // true
const m2 = moment("не дата");
console.log(m2.isValid()); // false
Важно понимать: объект Moment создаётся всегда, даже если входные данные некорректны. Ошибка не выбрасывается автоматически — вместо этого формируется объект с состоянием “invalid”.
Невалидные объекты возникают в нескольких типичных сценариях:
moment("32-13-2024").isValid(); // false
Парсер не может сопоставить строку с допустимым календарным форматом.
При использовании строгого разбора:
moment("2024/12/01", "YYYY-MM-DD", true).isValid(); // false
Третий параметр true включает строгую проверку, где даже
незначительное отклонение от формата делает результат невалидным.
moment("2024-02-30").isValid(); // false
Несуществующие календарные даты автоматически приводят к invalid-состоянию.
const m = moment("invalid date").add(5, "days");
m.isValid(); // false
Если исходный объект невалиден, любая последующая операция сохраняет это состояние.
Метод isValid() не просто проверяет флаг — он учитывает
внутреннюю структуру объекта, включая:
Пример безопасного паттерна:
const date = moment(userInput);
if (!date.isValid()) {
// обработка ошибки
}
Одной из частых причин неожиданных invalid-значений является различие между режимами парсинга.
moment("2024-12-01", "YYYY-MM-DD");
Библиотека пытается “угадать” структуру входных данных.
moment("2024-12-01", "YYYY-MM-DD", true);
Здесь любое отклонение от формата приводит к невалидному объекту.
Строгий режим особенно важен при обработке пользовательского ввода, API-данных и сериализованных строк.
Невалидный Moment имеет ряд характерных свойств:
isValid() возвращает false"Invalid date"const m = moment("invalid");
console.log(m.format("YYYY-MM-DD")); // "Invalid date"
Важно учитывать, что объект остаётся “живым”, но его значение не пригодно для вычислений.
Частая ошибка — проверка только после создания объекта и игнорирование последующих операций.
const m = moment("2024-01-01");
m.add(10000, "years");
console.log(m.isValid());
Хотя в большинстве случаев Moment.js корректно ограничивает диапазоны, при экстремальных значениях возможны переполнения, которые также должны проверяться.
Режим времени влияет на интерпретацию входных данных, но не отменяет проверку валидности:
moment.utc("2024-13-01").isValid(); // false
moment("2024-12-01").utc().isValid(); // true
Разница заключается в моменте интерпретации, а не в механизме валидации.
При копировании объектов Moment валидность сохраняется:
const m1 = moment("invalid");
const m2 = m1.clone();
console.log(m2.isValid()); // false
Это важно учитывать при передаче объектов между слоями приложения — ошибка не “исчезает” при копировании.
Типовой подход — централизованная проверка:
function parseDate(value) {
const m = moment(value);
if (!m.isValid()) {
return null;
}
return m;
}
Или выброс ошибки:
function strictParse(value) {
const m = moment(value);
if (!m.isValid()) {
throw new Error("Некорректная дата");
}
return m;
}
Важно различать:
moment(null).isValid(); // false
moment(undefined).isValid(); // false
Однако семантически это разные ситуации: отсутствие данных и некорректные данные требуют различной обработки.
При преобразовании в строку или JSON невалидные объекты не становятся ошибкой сериализации:
JSON.stringify({ date: moment("invalid") });
Результат будет зависеть от реализации, но чаще всего объект
превращается в пустой объект {} или строковое представление
"Invalid date" при явном вызове format().
const m = moment(input, moment.ISO_8601, true);
if (!m.isValid()) {
return fallbackValue;
}
return m.format("YYYY-MM-DD");
Или цепочка с ранним выходом:
const m = moment(userInput);
if (m.isValid() === false) return;
Любая цепочка методов сохраняет состояние:
const result = moment("invalid")
.add(2, "days")
.subtract(1, "month");
console.log(result.isValid()); // false
Это позволяет централизованно проверять итог, а не каждый шаг отдельно.
Moment хранит внутреннее состояние, которое обновляется при:
Флаг является финальным индикатором пригодности объекта к использованию в форматировании и вычислениях, и любые операции не способны “исправить” уже испорченный контекст без повторного парсинга исходных данных.