Обработка некорректных данных

Day.js использует принцип небросания исключений при некорректном вводе, вместо этого формируя объект с состоянием Invalid Date. Это ключевое поведение отличает библиотеку от ряда других решений, где ошибки парсинга приводят к выбросу исключений.

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

Создание даты и источники некорректных данных

Некорректные данные чаще всего возникают при:

  • передаче строк, не соответствующих ISO-формату;
  • работе с внешними API;
  • преобразовании пользовательского ввода;
  • сериализации/десериализации JSON;
  • ошибках в форматировании дат.

Примеры потенциально проблемных значений:

dayjs("2024-13-40")
dayjs("not-a-date")
dayjs(undefined)
dayjs(null)
dayjs({})

Во всех случаях Day.js не прерывает выполнение, а возвращает объект, состояние которого можно проверить.

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

Основной механизм контроля корректности — метод isValid().

const d1 = dayjs("2024-01-01")
const d2 = dayjs("invalid-date")

d1.isValid() // true
d2.isValid() // false

Метод не зависит от форматирования или последующих операций. Он отражает только внутреннее состояние объекта.

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

Поведение при форматировании некорректных дат

При вызове format() на недействительной дате возвращается строка:

Invalid Date
dayjs("broken").format("YYYY-MM-DD") // "Invalid Date"

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

Цепочки вызовов и распространение некорректного состояния

Day.js поддерживает иммутабельные цепочки. При этом состояние “invalid” сохраняется через все операции:

const result = dayjs("wrong")
  .add(2, "day")
  .subtract(1, "month")
  .format("YYYY-MM-DD")

Итоговый результат останется "Invalid Date", поскольку исходное значение уже некорректно.

Любые математические операции (add, subtract, set) не восстанавливают валидность.

Сравнение некорректных дат

При сравнении с использованием isBefore, isAfter, diff некорректные даты не дают осмысленного результата:

dayjs("invalid").isBefore(dayjs())
dayjs("invalid").isAfter(dayjs())
dayjs("invalid").diff(dayjs())

Поведение зависит от внутренней реализации, но в целом такие операции считаются недетерминированными. Основное правило — не использовать сравнения без предварительной проверки isValid().

Работа с пользовательским вводом

При обработке строкового ввода основная проблема заключается в неоднозначности форматов:

const input = "01-02-2024"
const date = dayjs(input)

date.isValid() // может быть false в зависимости от формата

Day.js по умолчанию строго ориентирован на ISO 8601. Неоднозначные форматы требуют использования дополнительных плагинов.

Плагин customParseFormat

При подключении customParseFormat становится возможной строгая интерпретация входных строк:

dayjs("01-02-2024", "DD-MM-YYYY", true).isValid()

Третий параметр включает строгий режим. При несоответствии формату результат всегда будет невалидным.

Некорректные значения из внешних API

При работе с JSON-ответами распространены следующие проблемы:

  • отсутствующие поля даты;
  • строки в неожиданном формате;
  • числовые timestamp в неправильной единице измерения.
const apiResponse = {
  createdAt: "2024/99/99"
}

const date = dayjs(apiResponse.createdAt)

if (!date.isValid()) {
  // обработка некорректного значения
}

Отсутствие проверки приводит к распространению значения "Invalid Date" в бизнес-логике.

Работа с null, undefined и пустыми значениями

Day.js интерпретирует отсутствующие значения как некорректные даты:

dayjs(null).isValid()       // false
dayjs(undefined).isValid()  // false
dayjs("").isValid()        // false

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

Поведение при числовых значениях

Числа интерпретируются как Unix timestamp (миллисекунды):

dayjs(0) // 1970-01-01T00:00:00Z
dayjs(1710000000000)

Некорректные числа (NaN, Infinity) приводят к невалидной дате:

dayjs(NaN).isValid()      // false
dayjs(Infinity).isValid() // false

Контроль ошибок через нормализацию данных

Один из устойчивых подходов — централизованная нормализация входных значений:

function safeDate(value) {
  const d = dayjs(value)
  return d.isValid() ? d : null
}

Такой подход исключает распространение строкового значения "Invalid Date" по системе и заменяет его явным отсутствием данных.

Особенности сериализации

При сериализации объектов Day.js некорректные даты не превращаются в валидные ISO-строки:

JSON.stringify(dayjs("bad"))

Результат зависит от внутреннего состояния объекта, но при невалидной дате стандартное поведение не гарантирует корректного формата, поэтому требуется предварительная проверка.

Влияние временных зон на валидность

Некорректные временные зоны не всегда приводят к невалидной дате, но могут изменять интерпретацию:

dayjs("2024-01-01T00:00:00+99:00")

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

Общие принципы устойчивой обработки

Корректная работа с некорректными данными в Day.js строится на следующих принципах:

  • проверка isValid() после любого парсинга;
  • исключение прямого использования результата без валидации;
  • нормализация входных данных до создания объекта;
  • изоляция внешних источников данных;
  • отказ от цепочек вычислений на невалидных объектах;
  • явное представление отсутствующих дат через null или аналогичные структуры.