Проверка существования даты

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

С точки зрения Luxon, «существование даты» не означает её наличие в календаре как абстрактного факта, а означает валидность внутреннего представления времени. Любая операция создания даты возвращает объект DateTime, который всегда существует как экземпляр, но может быть помечен как недействительный.


Валидность как основа проверки существования

Главный механизм проверки существования даты — свойство:

  • DateTime.isValid

Это булево значение, которое указывает, корректно ли был создан объект.

import { DateTime } from "luxon";

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

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

Несмотря на то, что объект dt существует, сама дата не существует в календарном смысле, поскольку 30 февраля не может быть корректно интерпретировано.

Таким образом, в Luxon важно различать:

  • существование объекта DateTime
  • существование (валидность) даты внутри него

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

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

invalidReason

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

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

Основные значения invalidReason:

  • "unparsable" — строка не может быть разобрана
  • "invalid input" — переданы некорректные параметры
  • "unsupported zone" — неподдерживаемая временная зона
  • "missing field" — отсутствуют обязательные поля
  • "out of range" — значения выходят за допустимые пределы

invalidExplanation

Для более подробной диагностики используется:

console.log(dt.invalidExplanation);

Это человекочитаемое описание причины, например:

  • «the input “2025-02-30” cannot be parsed as a valid calendar date»

Проверка существования даты при создании

ISO-строки

Наиболее распространённый способ создания даты:

const dt = DateTime.fromISO("2025-12-10");

if (!dt.isValid) {
  // дата не существует
}

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

  • корректность месяца (1–12)
  • корректность дня в месяце
  • корректность високосных годов
  • согласованность времени

Некорректные даты в ISO

DateTime.fromISO("2024-02-29").isValid; // true (високосный год)
DateTime.fromISO("2023-02-29").isValid; // false

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


Проверка при ручной сборке даты

Luxon позволяет создавать даты через объект:

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

Здесь возникает проверка диапазонов:

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

Причина:

  • месяц 13 не существует

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

Luxon строго контролирует диапазоны:

  • месяц: 1–12
  • день: зависит от месяца и года
  • час: 0–23
  • минута: 0–59
  • секунда: 0–59 (с учётом leap seconds ограниченно)
  • миллисекунды: 0–999

Любое нарушение приводит к невалидной дате.


Проверка существования после операций

Некорректная дата может появиться не только при создании, но и при преобразованиях.

Добавление интервалов

const dt = DateTime.fromISO("2025-01-31").plus({ months: 1 });

console.log(dt.toISO());

Результат зависит от стратегии нормализации:

  • Luxon корректирует дату, если возможно
  • при невозможности может вернуть невалидный объект

Работа с временными зонами

Одной из частых причин несуществующих дат является зона времени.

const dt = DateTime.fromISO("2025-06-10T12:00", {
  zone: "invalid-zone"
});

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

Luxon фиксирует:

  • неподдерживаемые IANA-зоны
  • некорректные смещения
  • конфликты локального времени при переходе на летнее время

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

fromFormat

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

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

Здесь проверка происходит в два этапа:

  1. соответствие шаблону
  2. календарная корректность результата

Различие между null, undefined и невалидной датой

Важно различать три состояния:

1. undefined

let dt;

Дата не существует как переменная.

2. null

const dt = null;

Явное отсутствие объекта.

3. Invalid DateTime

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

Объект существует, но дата невалидна:

dt.isValid; // false

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

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

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

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

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


Проверка до использования значений

Любая операция с датой должна учитывать валидность:

function formatDate(dt) {
  if (!dt.isValid) {
    return "invalid date";
  }

  return dt.toFormat("dd.MM.yyyy");
}

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


Особенности поведения при арифметике

При операциях сложения и вычитания Luxon стремится сохранить валидность:

const dt = DateTime.fromISO("2025-01-31").plus({ months: 1 });

console.log(dt.isValid);

Если корректная нормализация невозможна, объект становится невалидным, и это фиксируется через isValid.


Влияние парсинга частичных данных

При неполных данных Luxon может заполнить отсутствующие поля:

const dt = DateTime.fromObject({ year: 2025 });

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

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


Типовые сценарии проверки существования

Валидация пользовательского ввода

const input = "31/04/2025";

const dt = DateTime.fromFormat(input, "dd/MM/yyyy");

if (!dt.isValid) {
  // дата не существует
}

Проверка API-данных

function parseEvent(data) {
  const start = DateTime.fromISO(data.start);

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

  return start;
}

Фильтрация временных диапазонов

const range = dates.filter(d =>
  d.isValid && d.year === 2025
);

Использование диагностических свойств при отладке

Для глубокого анализа используется связка:

  • isValid
  • invalidReason
  • invalidExplanation
const dt = DateTime.fromISO("2025-02-30");

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

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


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

Luxon сохраняет неизменяемость объектов:

const dt1 = DateTime.fromISO("2025-02-30");
const dt2 = dt1.plus({ days: 1 });

console.log(dt1.isValid); // false
console.log(dt2.isValid); // false

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


Практический паттерн безопасной работы

Общий подход к проверке существования даты строится вокруг единственного правила: любая дата должна быть проверена через isValid до дальнейшего использования.

function safeDate(input) {
  const dt = DateTime.fromISO(input);

  return dt.isValid ? dt : null;
}

Такой подход исключает попадание несуществующих дат в бизнес-логику и обеспечивает предсказуемость обработки времени.