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

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

Основные признаки невалидного значения:

  • DateTime.isValid === false
  • DateTime.invalidReason содержит тип причины
  • DateTime.invalidExplanation содержит текстовое пояснение

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


Базовые причины невалидности DateTime

Некорректный формат входных данных

Наиболее частая причина — попытка создать дату из строки, не соответствующей ожидаемым форматам ISO или пользовательскому формату.

import { DateTime } from "luxon";

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

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

Типичные случаи:

  • неправильный порядок компонентов даты
  • недопустимые значения месяца и дня
  • отсутствие обязательных разделителей
  • смешение форматов (например, ISO и локального)

Выход значений за допустимые диапазоны

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

DateTime.fromObject({ year: 2024, month: 0, day: 10 });

Причины:

  • месяц вне диапазона 1–12
  • день вне диапазона для конкретного месяца
  • отрицательные или нулевые значения в календарных полях

В этом случае invalidReason часто принимает значение:

  • unit out of range

Ошибки часовых поясов

Работа с временными зонами — один из источников невалидных значений.

DateTime.fromObject(
  { year: 2024, month: 5, day: 10 },
  { zone: "Mars/Phobos" }
);

Если зона не распознана:

  • invalidReason = "unsupported zone"

Типичные проблемы:

  • опечатки в идентификаторе IANA
  • использование нестандартных или устаревших зон
  • передача произвольной строки вместо валидного идентификатора

Конфликтующие параметры создания

При создании объекта через fromObject или set могут возникать противоречивые комбинации.

DateTime.fromObject({
  year: 2024,
  ordinal: 400
});

Здесь одновременно заданы несовместимые представления даты (календарная и порядковая).

Возможные причины:

  • смешение календарных и ordinal/weekday значений
  • конфликтующие поля времени
  • неоднозначная комбинация входных параметров

Невалидные исходные значения JavaScript Date

Luxon опирается на встроенный Date. Если он не может быть построен, результат становится невалидным.

const dt = DateTime.fromJSDate(new Date("invalid"));
console.log(dt.isValid); // false

Причины:

  • NaN внутри JS Date
  • некорректная строка при парсинге Date
  • переполнение диапазона времени (очень большие значения)

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

ISO-парсинг

Метод fromISO требует строгого соответствия стандарту.

Ошибки:

  • отсутствует временная часть при ожидании datetime
  • неправильный разделитель (/ вместо -)
  • неверный порядок компонентов
DateTime.fromISO("2024-05-40T10:00");

Результат:

  • invalidReason = "unparsable"

RFC и HTTP форматы

При использовании fromHTTP, fromRFC2822 возможны ошибки разбора:

  • нестандартные сокращения месяцев
  • неправильные часовые смещения
  • лишние символы

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

При fromFormat критично совпадение шаблона и строки.

DateTime.fromFormat("32-01-2024", "dd-MM-yyyy");

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

  • несоответствие шаблону
  • недопустимые символы
  • отсутствие обязательных частей

Невалидность в Duration

Хотя Duration менее строг, он также может стать невалидным.

import { Duration } from "luxon";

const d = Duration.fromObject({ hours: "x" });

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

Причины:

  • некорректные типы значений (строки вместо чисел)
  • невозможность приведения к числу
  • NaN в вычислениях

Невалидность Interval

Interval становится невалидным, если нарушена структура границ.

import { DateTime, Interval } from "luxon";

const start = DateTime.fromISO("2024-05-10");
const end = DateTime.fromISO("invalid");

const interval = Interval.fromDateTimes(start, end);

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

Основные причины:

  • одна из границ невалидна
  • отсутствует start или end
  • невозможность интерпретации входных DateTime

Типовые значения invalidReason

Внутренний механизм Luxon классифицирует ошибки через строковые коды:

  • unparsable — строка не может быть разобрана
  • unit out of range — значение выходит за пределы календаря
  • unsupported zone — неизвестная временная зона
  • conflicting specifications — противоречивые входные данные

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


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

Любая операция над невалидным DateTime сохраняет его состояние:

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

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

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

Особенность модели:

  • ошибки не выбрасываются
  • результат «протаскивает» невалидность дальше по цепочке
  • вычисления становятся безопасными с точки зрения runtime

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

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

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

console.log(dt.invalidExplanation);

Использование:

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

Системная природа невалидности

Невалидность в Luxon — не исключение и не сбой выполнения, а часть модели данных. Она возникает как результат строгой проверки входных параметров и распространяется через все операции, сохраняя информацию о первоначальной причине.

Такой подход формирует предсказуемое поведение:

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