Проверка корректности DateTime

Проверка корректности объекта DateTime в Luxon опирается на внутреннюю модель состояния экземпляра, где каждый созданный объект либо считается валидным временем, либо помечается как невалидный с указанием причины. Это принципиально отличает Luxon от ряда более простых библиотек: вместо возврата null или исключений при ошибке парсинга создаётся объект DateTime, который сохраняет диагностическую информацию о проблеме.

Базовый механизм контроля корректности — свойство isValid. Оно возвращает булево значение и отражает, может ли экземпляр DateTime быть использован в вычислениях.

import { DateTime } from "luxon";

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

console.log(dt.isValid); // false

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

Причины невалидности: invalidReason

Для точной диагностики используется свойство invalidReason, которое возвращает краткий код ошибки.

const dt = DateTime.fromISO("not-a-date");

console.log(dt.isValid); // false
console.log(dt.invalidReason); // "unparsable"

Основные категории причин:

  • unparsable — строка не может быть распознана как дата
  • invalidInput — переданы некорректные входные данные
  • unsupported zone — указанная временная зона не поддерживается
  • conflicting specification — противоречивые параметры создания DateTime
  • missing field — отсутствуют обязательные компоненты даты/времени

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

Подробное описание ошибки: invalidExplanation

Для более детального анализа используется invalidExplanation, возвращающий человекочитаемое описание.

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

console.log(dt.isValid); // false
console.log(dt.invalidReason); // "invalid unit month"
console.log(dt.invalidExplanation); // "unit month out of range"

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

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

Наиболее частый источник невалидных DateTime — парсинг строковых представлений.

ISO-строки

DateTime.fromISO("2024-02-30").isValid; // false

Luxon строго валидирует календарные значения. Например, 30 февраля автоматически помечается как некорректная дата.

Пользовательские форматы

DateTime.fromFormat("31-02-2024", "dd-MM-yyyy").isValid; // false

Даже если строка соответствует шаблону, значения проходят семантическую проверку календаря.

JavaScript Date

DateTime.fromJSDate(new Date("invalid")).isValid; // false

Если исходный Date содержит NaN, Luxon корректно переносит это состояние в DateTime.

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

Одним из частых источников невалидных объектов являются некорректные идентификаторы временных зон.

const dt = DateTime.now().setZone("Mars/Phobos");

console.log(dt.isValid); // false
console.log(dt.invalidReason); // "unsupported zone"

Luxon опирается на IANA Time Zone Database. Любая строка, не входящая в этот набор, считается ошибочной.

Корректный пример:

DateTime.now().setZone("Europe/Almaty").isValid; // true

Проверка входных данных перед созданием DateTime

На уровне архитектуры часто требуется предварительная валидация входных значений до создания объекта.

Защита от undefined и null

function safeFromISO(value) {
  if (typeof value !== "string") return null;

  const dt = DateTime.fromISO(value);
  return dt.isValid ? dt : null;
}

Такой подход предотвращает распространение невалидных объектов в системе.

Проверка числовых компонентов

function safeFromObject(obj) {
  const dt = DateTime.fromObject(obj);
  if (!dt.isValid) {
    console.error(dt.invalidExplanation);
    return null;
  }
  return dt;
}

Цепочки операций и потеря валидности

В Luxon все трансформации сохраняют состояние валидности. Если исходный объект невалиден, он остаётся невалидным на каждом последующем шаге.

const dt = DateTime.fromISO("invalid")
  .plus({ days: 2 })
  .setZone("Europe/Almaty");

console.log(dt.isValid); // false

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

Типовые причины ошибок при создании DateTime

1. Выход за пределы календаря

DateTime.fromObject({ year: 2024, month: 2, day: 30 }).isValid; // false

2. Некорректные типы данных

DateTime.fromObject({ year: "2024", month: "02" }).isValid; // false

Luxon не выполняет автоматическое приведение типов.

3. Противоречивые параметры

DateTime.fromObject({
  year: 2024,
  hour: 10,
  weekYear: 2023
}).isValid; // false

Разные системы отсчёта времени (календарная и недельная) могут конфликтовать.

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

При арифметике с датами важно учитывать, что результат всегда наследует валидность исходного объекта.

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

const result = start.plus({ days: 10 });

console.log(result.isValid); // false

Даже корректная операция не восстанавливает объект, если он уже повреждён.

Практический паттерн централизованной проверки

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

function assertDateTime(dt) {
  if (!dt.isValid) {
    throw new Error(dt.invalidExplanation);
  }
  return dt;
}

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

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

Поведение при сериализации

Невалидные объекты при преобразовании в строку не выбрасывают исключение:

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

console.log(dt.toISO()); // null

Такой результат позволяет безопасно сериализовать данные без аварийных падений, но требует обязательной проверки isValid до вывода.