Ошибки при разборе

В библиотеке Luxon разбор (parsing) временных значений строится вокруг строгой модели DateTime. Любая входная строка или объект преобразуется в внутреннее представление, которое либо становится валидным экземпляром даты-времени, либо фиксируется как невалидное состояние. Ошибки при разборе не выбрасываются как исключения, а выражаются через флаг isValid и диагностическое поле invalidReason, что делает модель поведения предсказуемой, но требует внимательного анализа результата.

В основе обработки входных данных лежит принцип: любое несоответствие формату не приводит к аварийному завершению, а маркирует объект как невалидный.

import { DateTime } from "luxon";

const dt = DateTime.fromISO("2024-13-40");
console.log(dt.isValid); // false
console.log(dt.invalidReason); // 'unparsable'

Основные причины, по которым разбор завершается неудачно:

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

Ошибки разбора ISO-строк

Метод fromISO является наиболее часто используемым механизмом, однако он чувствителен к строгому соответствию стандарту ISO 8601.

DateTime.fromISO("2024-02-30"); // невалидная дата
DateTime.fromISO("2024-02-10T25:00:00"); // неверный час

Типовые проблемы:

Некорректная календарная дата

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

Нарушение временных границ

Часы должны находиться в диапазоне 0–23, минуты и секунды — 0–59. Значения вне диапазона делают результат невалидным.

Ошибки при разборе строк нестандартных форматов

Метод fromFormat требует точного соответствия шаблону. Любое отклонение ломает разбор.

DateTime.fromFormat("31/12/2024", "yyyy-MM-dd"); // invalid

Ключевые источники ошибок:

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

Особенно критичны текстовые месяцы:

DateTime.fromFormat("31 Dec 2024", "dd MMM yyyy", { locale: "fr" });

При несовпадении локали сокращения месяцев перестают распознаваться.

Ошибки временных зон

Luxon опирается на IANA Time Zone Database. Любая некорректная зона приводит к невалидному объекту.

DateTime.fromISO("2024-01-01T10:00", { zone: "Europe/Nowhere" });

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

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

В таких случаях поле invalidReason обычно содержит значение unsupported zone.

Ошибки при разборе Date из JavaScript

При использовании fromJSDate ошибки возникают не в формате строки, а на уровне переданного объекта.

DateTime.fromJSDate("2024-01-01"); // строка вместо Date

Критические случаи:

  • передача строки вместо объекта Date
  • использование Invalid Date
  • повреждённые значения, полученные из сторонних API

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

Нормализация и скрытые ошибки

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

DateTime.fromISO("2024-02-29"); // валидно только в високосный год

Если дата формально существует, но логика приложения ожидает иные ограничения, ошибка становится семантической, а не синтаксической.

Ошибки локали при разборе

Локаль влияет на интерпретацию строковых форматов.

DateTime.fromFormat("01-12-2024", "dd-MM-yyyy", { locale: "en" });
DateTime.fromFormat("01-12-2024", "dd-MM-yyyy", { locale: "ru" });

Проблемные ситуации:

  • различие в порядках день/месяц
  • неоднозначные числовые форматы
  • текстовые представления месяцев и дней недели

При несоответствии локали результат становится невалидным без явной ошибки.

Поведение invalidReason и диагностика

Поле invalidReason используется для классификации ошибок разбора:

  • unparsable — строка не распознана
  • invalid input — некорректный тип входных данных
  • unsupported zone — неподдерживаемая временная зона
  • conflicting specification — противоречивые параметры
const dt = DateTime.fromFormat("2024/31/12", "yyyy-MM-dd");
console.log(dt.invalidReason);

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

Ошибки при цепочках преобразований

Ошибки часто возникают не на этапе первичного разбора, а при последовательных преобразованиях:

const dt = DateTime.fromISO("2024-01-01")
  .setZone("invalid-zone")
  .toFormat("yyyy-MM-dd");

В таких цепочках:

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

Потеря данных при неявных преобразованиях

Некоторые операции приводят к неочевидной потере информации:

  • округление до начала дня при смене зоны
  • смещение даты при переходе между часовыми поясами
  • интерпретация локального времени как UTC
DateTime.fromISO("2024-01-01T00:30", { zone: "UTC" })
  .setZone("Asia/Almaty");

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

Ошибки при работе с частичными датами

Luxon поддерживает неполные строки только при определённых форматах. Частичные данные часто становятся источником невалидных объектов:

DateTime.fromISO("2024-01"); // может интерпретироваться неоднозначно

Проблемы:

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

Особенности поведения при отсутствии исключений

Ключевая особенность модели заключается в отсутствии throw-ошибок при разборе. Это приводит к необходимости явной проверки:

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

if (!dt.isValid) {
  // обработка ошибки разбора
}

Игнорирование этого свойства приводит к накоплению скрытых дефектов в данных и последующим логическим ошибкам в вычислениях времени.