Неправильный формат

В библиотеке Luxon некорректный формат возникает в момент, когда входная строка или структура данных не соответствует ожидаемому шаблону парсинга. В отличие от стандартного Date в JavaScript, который при ошибке часто возвращает Invalid Date без подробностей, Luxon формирует объект DateTime с расширенной диагностикой состояния ошибки.

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


Основные источники некорректного формата

Несоответствие ISO 8601

Наиболее частая причина — отклонение от стандарта ISO 8601.

import { DateTime } from "luxon";

const dt = DateTime.fromISO("2024-13-40T25:61:00");

Строка синтаксически похожа на ISO, но содержит невозможные значения:

  • месяц 13
  • день 40
  • часы 25
  • минуты 61

Результат:

dt.isValid // false

Ошибки пользовательского формата fromFormat

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

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

Здесь формат соответствует шаблону, но дата не существует (февраль не содержит 31 день).

Результат не будет выбрасывать ошибку, но объект станет невалидным.


Несовпадение локали

Форматы, зависящие от локали, часто приводят к некорректному разбору.

const dt = DateTime.fromFormat("12 janvier 2024", "d MMMM yyyy", {
  locale: "en"
});

Если локаль не соответствует входной строке, месяц не распознаётся.


Неподдерживаемые строки времени

Некоторые форматы выглядят корректными, но не поддерживаются парсером Luxon:

DateTime.fromISO("2024-05-20 10:00:00") // пробел вместо T

Хотя многие библиотеки это допускают, Luxon строго следует ISO.


Состояние объекта DateTime при ошибке

При некорректном формате Luxon не возвращает null или undefined. Вместо этого создаётся объект со следующими свойствами:

  • isValid: false
  • invalidReason: string
  • invalidExplanation: string

Пример:

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

console.log(dt.isValid); // false
console.log(dt.invalidReason); // "unparsable"
console.log(dt.invalidExplanation); // более подробное описание

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

unparsable

Возникает, когда строка не может быть разобрана вообще:

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

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

  • мусорные строки
  • случайные символы
  • неполные даты

invalid input

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

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

missing unit

Возникает при неполных данных:

DateTime.fromObject({ year: 2024 });

Без месяца и дня невозможно построить полноценную дату.


invalid format

Часто связан с fromFormat:

DateTime.fromFormat("2024/05/20", "dd-MM-yyyy");

Формат не соответствует входной строке.


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

fromISO

Строго проверяет ISO-8601.

DateTime.fromISO("2024-05-20T10:00:00").isValid; // true
DateTime.fromISO("2024/05/20").isValid; // false

fromFormat

Зависит от шаблона:

DateTime.fromFormat("20-05-2024", "dd-MM-yyyy");

Любое отклонение приводит к invalid.


fromObject

Строго проверяет диапазоны значений:

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

Месяц 0 — недопустим.


fromMillis и fromSeconds

Ошибки возникают при NaN:

DateTime.fromMillis(NaN).isValid; // false

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

Основной механизм контроля:

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

if (!dt.isValid) {
  console.log(dt.invalidReason);
}

Ключевые свойства

  • isValid — главный индикатор
  • invalidReason — тип ошибки
  • invalidExplanation — подробное описание

Типичные сценарии возникновения некорректного формата

Пользовательский ввод

Наиболее частая причина — текстовые поля:

DateTime.fromFormat(userInput, "dd.MM.yyyy");

Ошибки:

  • лишние пробелы
  • неверные разделители
  • неполная дата

Данные из API

API часто возвращают неоднородные форматы:

{
  "date": "2024-05-20 10:00:00"
}

Luxon ожидает ISO:

DateTime.fromISO(api.date);

Конвертация между зонами

Некорректный формат может появляться при ошибках временных зон:

DateTime.fromISO("2024-05-20T10:00:00", { zone: "invalid-zone" });

Строгая типизация дат в Luxon

Luxon не пытается «угадать» формат. Это принципиальное отличие от более гибких библиотек.

Сравнение поведения:

  • некорректный ввод → DateTime с isValid: false
  • нет автоматических исправлений
  • нет неявного преобразования форматов

Обработка некорректных значений

Проверка перед использованием

const dt = DateTime.fromISO(input);

if (!dt.isValid) {
  return null;
}

Запасной формат

let dt = DateTime.fromISO(input);

if (!dt.isValid) {
  dt = DateTime.fromFormat(input, "dd.MM.yyyy");
}

Фильтрация массива дат

const dates = ["2024-01-01", "invalid", "2024-02-01"];

const validDates = dates
  .map(d => DateTime.fromISO(d))
  .filter(dt => dt.isValid);

Особенности invalidExplanation

Поле invalidExplanation предназначено для диагностики и содержит человекочитаемое описание.

Пример:

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

console.log(dt.invalidExplanation);

Типичные варианты:

  • invalid input
  • the input is not a valid ISO 8601 date
  • unit out of range

Проблемы при цепочках операций

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

const dt = DateTime.fromISO("invalid")
  .plus({ days: 2 })
  .toISO();

Результат:

  • все последующие операции сохраняют isValid: false

Работа с библиотечными преобразованиями

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

  • ISO → custom format
  • timestamp → DateTime
  • DateTime → JSON
JSON.stringify(DateTime.fromISO("invalid"));

Результат:

{ "invalid": true }

Отличие от исключений

Важная особенность Luxon — отсутствие выбрасываемых ошибок при парсинге.

Неверный формат:

  • не прерывает выполнение
  • не вызывает throw
  • возвращает объект с состоянием ошибки

Это позволяет безопасно обрабатывать массовые данные без try/catch.


Практика нормализации входных данных

Очистка строки

const cleaned = input.trim();
const dt = DateTime.fromISO(cleaned);

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

function parseDate(input) {
  return DateTime.fromISO(input) ||
         DateTime.fromFormat(input, "dd.MM.yyyy");
}

Жёсткая валидация

function strictParse(input) {
  const dt = DateTime.fromISO(input);
  if (!dt.isValid) return null;
  return dt;
}

Типичные ошибки разработчиков

Игнорирование isValid

const dt = DateTime.fromISO(input);
console.log(dt.toISO()); // может быть null-результат

Предположение о «починке» даты

DateTime.fromISO("2024-13-40") // не исправляется автоматически

Смешивание форматов

DateTime.fromISO("20-05-2024");

ISO не допускает таких строк.


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

Некорректные объекты сохраняют состояние:

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

JSON.stringify(dt);

Результат:

{"invalid":true}

Влияние локали и временной зоны

Некорректный формат может возникнуть из-за:

  • неправильной локали при fromFormat
  • отсутствующей зоны
  • несовместимости формата и зоны
DateTime.fromFormat("20/05/2024", "dd.MM.yyyy", {
  locale: "en"
});

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

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

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

const next = dt.plus({ days: 1 });

next.isValid; // false

Диагностический подход

Структурный разбор некорректного формата включает:

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

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