Day.js строит работу с датами вокруг неизменяемых объектов, поведение которых при некорректных входных данных строго детерминировано. Любое значение, не распознанное как валидная дата, приводит к формированию специального объекта состояния «invalid», который сохраняется на всём протяжении цепочки операций.
При создании экземпляра:
dayjs('не дата')
dayjs(undefined)
dayjs(null)
dayjs({})
результатом становится объект с внутренним флагом невалидности. В
отличие от стандартного Date, библиотека не пытается
«исправить» входные данные эвристиками, если не подключены
дополнительные плагины.
Любая операция над невалидным объектом сохраняет его невалидное состояние.
const d = dayjs('not-a-date');
d.add(1, 'day'); // invalid
d.format('YYYY-MM-DD'); // "Invalid Date"
d.diff(dayjs()); // NaN
Ключевой принцип: ошибка не маскируется и не преобразуется в текущую дату. Это важно для предотвращения скрытых дефектов в данных.
Основной инструмент диагностики — метод проверки состояния:
dayjs('2024-01-01').isValid(); // true
dayjs('bad input').isValid(); // false
isValid() работает на основе внутреннего флага парсинга
и не выполняет повторный разбор строки. Это делает его дешёвым по
производительности и безопасным для массовой проверки данных, например
при обработке API-ответов.
Некорректные значения чаще всего возникают на границах системы:
API-ответы с неполными данными
{ "date": "" }
{ "date": null }
{ "date": "0000-00-00" }Пользовательский ввод
JSON-десериализация
Базы данных
Перед созданием объекта даты часто применяется явная проверка входного значения:
function parseDate(input) {
if (!input || typeof input !== 'string') return null;
const d = dayjs(input);
return d.isValid() ? d : null;
}
Такой подход позволяет отделить слой валидации от бизнес-логики и не распространять invalid-объекты дальше по цепочке вычислений.
Метод format() при невалидной дате возвращает
фиксированное значение:
dayjs('invalid').format('YYYY-MM-DD'); // "Invalid Date"
Это поведение нельзя переопределить через форматную строку. Поэтому при выводе данных требуется предварительная проверка валидности:
const d = dayjs(value);
const output = d.isValid()
? d.format('YYYY-MM-DD')
: '';
Любая цепочка методов наследует состояние исходного объекта:
const result = dayjs('bad')
.add(5, 'day')
.subtract(1, 'month')
.format();
Результат всегда будет невалидным, независимо от количества промежуточных операций. Это исключает частично корректные вычисления на ошибочных данных.
Некорректные числовые входы также приводят к invalid-состоянию:
dayjs(NaN).isValid(); // false
dayjs(0/0).isValid(); // false
При этом числовые таймстемпы интерпретируются строго:
dayjs(1690000000000).isValid(); // true
Ошибки часто возникают при неявном приведении типов:
dayjs("1690000000000") // строка может быть корректно распознана
Но поведение зависит от формата и настроек парсинга.
Для уменьшения количества некорректных дат применяется плагин строгого разбора:
import customParseFormat from 'dayjs/plugin/customParseFormat'
dayjs.extend(customParseFormat)
Пример строгого формата:
dayjs('31-02-2024', 'DD-MM-YYYY', true).isValid(); // false
Третий аргумент true включает жёсткую проверку,
исключающую несуществующие даты.
Частая проблема — частично заполненные строки:
"2024-01""2024""01-01"Day.js может интерпретировать такие значения как валидные в зависимости от режима парсинга, что требует явной нормализации входных данных.
Типовой подход:
function normalize(input) {
if (!/^\d{4}-\d{2}-\d{2}$/.test(input)) return null;
return dayjs(input);
}
При работе с API целесообразно централизовать обработку:
function safeDate(value) {
const d = dayjs(value);
return d.isValid() ? d : null;
}
Дополнительно может применяться логирование аномалий:
if (!d.isValid()) {
console.warn('Invalid date received:', value);
}
Некорректная дата ломает все производные вычисления:
diff() → NaNunix() → NaNvalueOf() → NaNdayjs('bad').valueOf(); // NaN
Это особенно критично при агрегациях и сортировках:
dates.sort((a, b) => dayjs(a).valueOf() - dayjs(b).valueOf());
Наличие invalid-значений приводит к непредсказуемому порядку.
При обработке массивов используется фильтрация:
const validDates = dates
.map(dayjs)
.filter(d => d.isValid());
Либо агрессивное отбрасывание:
const timestamps = dates
.map(d => dayjs(d))
.filter(Boolean)
.map(d => d.valueOf());
При использовании дополнительных расширений, таких как UTC, invalid-состояние сохраняется независимо от контекста:
dayjs.utc('invalid').isValid(); // false
Это означает, что временная зона не влияет на корректность исходного парсинга, а только на интерпретацию уже валидного значения.
Некорректные даты часто возникают не только из-за синтаксиса, но и из-за логических ограничений:
Проверка диапазонов:
function isReasonable(d) {
const ts = d.valueOf();
return ts > 0 && ts < Date.now() + 10 * 365 * 24 * 60 * 60 * 1000;
}
Стабильная работа с датами строится на принципе:
isValid()Игнорирование этого порядка приводит к распространению invalid-объектов по всей бизнес-логике и нарушению детерминированности вычислений.