Проверка валидности через isValid

Модель валидности в DateTime

Внутреннее представление даты и времени в Luxon основано на объекте DateTime, который может находиться в двух состояниях: корректном и некорректном (invalid). Любая операция создания, преобразования или вычисления может привести к результату, который формально является объектом DateTime, но не представляет реальную календарную дату.

Для контроля состояния используется свойство:

  • isValid — булево значение, отражающее корректность объекта

Если isValid === false, объект считается недействительным и большинство операций над ним возвращают предсказуемые безопасные результаты.


Базовая проверка валидности

Свойство isValid является основным инструментом диагностики:

import { DateTime } from "luxon";

const dt = DateTime.fromISO("2024-13-40");

dt.isValid; // false

В примере строка содержит некорректные значения месяца и дня. Luxon не выбрасывает исключение, а формирует объект с флагом невалидности.

Корректный случай:

const dt = DateTime.fromISO("2024-12-01");

dt.isValid; // true

Причины невалидного состояния

При isValid === false дополнительно доступны диагностические поля:

  • invalidReason — краткий код причины
  • invalidExplanation — текстовое описание
const dt = DateTime.fromISO("2024-02-30");

dt.isValid;              // false
dt.invalidReason;        // 'unit out of range'
dt.invalidExplanation;   // 'the day "30" is out of range for month "2"'

Типичные причины:

1. Выход за диапазон календарных значений

Неверные дни, месяцы, часы:

DateTime.fromObject({ year: 2024, month: 13, day: 1 });

2. Некорректный формат строки

DateTime.fromISO("not-a-date");

3. Отсутствие обязательных данных

DateTime.fromObject({ hour: 10 }); // без даты интерпретация может быть invalid

4. Ошибки при парсинге временных зон

DateTime.fromISO("2024-12-01T10:00", { zone: "Invalid/Zone" });

Поведение методов при invalid-состоянии

Luxon придерживается модели «без исключений» при работе с датами. Поэтому invalid-объекты не прерывают выполнение программы, но распространяют невалидность по цепочке.

const dt = DateTime.fromISO("2024-02-30");

const shifted = dt.plus({ days: 5 });

shifted.isValid; // false

Любая операция над невалидным объектом сохраняет состояние invalid.


Безопасное использование isValid в цепочках

При работе с преобразованиями проверка может выполняться на любом этапе:

const dt = DateTime.fromFormat("31/02/2024", "dd/MM/yyyy");

if (dt.isValid) {
  const result = dt.toISO();
}

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


Связь isValid с форматированием и выводом

Невалидные объекты не приводятся к нормальному строковому представлению календарной даты.

const dt = DateTime.fromISO("invalid");

dt.toISO();      // null
dt.toString();   // 'Invalid DateTime'

Любые методы форматирования возвращают безопасные значения:

  • toISO()null
  • toFormat() → пустая строка или некорректный результат
  • toString() → строка с обозначением invalid

Диагностика через invalidReason и invalidExplanation

isValid определяет факт ошибки, но не её природу. Для анализа используется расширенная информация:

const dt = DateTime.fromObject({ year: 2024, month: 0 });

dt.isValid; // false
dt.invalidReason; // 'unit out of range'

Часто встречающиеся значения invalidReason:

  • unsupported zone
  • unparsable
  • unit out of range
  • missing field

Эти коды позволяют классифицировать ошибки на уровне бизнес-логики.


Поведение при преобразованиях между типами

fromJSDate

const dt = DateTime.fromJSDate(new Date("invalid-date"));

dt.isValid; // false

fromMillis

const dt = DateTime.fromMillis(NaN);

dt.isValid; // false

fromObject

DateTime.fromObject({ year: NaN, month: 5 }).isValid; // false

Любое некорректное числовое значение автоматически приводит к invalid-состоянию.


Наследование invalid-состояния

Invalid-объект сохраняет свою невалидность независимо от операций:

const dt = DateTime.fromISO("invalid");

const result = dt
  .set({ year: 2025 })
  .plus({ days: 10 })
  .startOf("day");

result.isValid; // false

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


Проверка валидности в условиях и фильтрации

При работе с массивами дат часто используется фильтрация:

const dates = [
  DateTime.fromISO("2024-01-01"),
  DateTime.fromISO("2024-02-30"),
  DateTime.fromISO("2024-03-01")
];

const validDates = dates.filter(d => d.isValid);

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


Отличие isValid от проверок через null и undefined

Luxon не использует null как индикатор ошибки для DateTime. Вместо этого всегда возвращается объект:

  • корректный объект → isValid === true
  • ошибочный объект → isValid === false

Это исключает необходимость проверки на существование объекта:

const dt = DateTime.fromISO("bad");

dt === null; // false
dt.isValid;  // false

Роль isValid в архитектуре обработки времени

Использование isValid формирует устойчивую модель обработки временных данных:

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

Такой подход позволяет разделять этапы:

  • создание объекта
  • вычисления и трансформации
  • финальная валидация перед использованием результата