Проверка функций

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

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

Объект DateTime содержит встроенные механизмы валидации, позволяющие определить, был ли он создан успешно или возникла ошибка при разборе входных данных.

Основной индикатор состояния — свойство isValid:

import { DateTime } from "luxon";

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

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

Если входная строка не соответствует ISO-формату или содержит некорректные значения (например, 13-й месяц), объект всё равно создаётся, но помечается как невалидный.

Для диагностики причины используется invalidReason:

console.log(dt.invalidReason);
// "unparsable" или "out of range" (в зависимости от ошибки)

Дополнительно применяется invalidExplanation, предоставляющий более подробное описание:

console.log(dt.invalidExplanation);

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


Проверка результата различных способов создания DateTime

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

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

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

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

fromMillis

const b = DateTime.fromMillis(1710000000000);

if (b.isValid) {
  console.log(b.toISO());
}

fromMillis почти всегда возвращает валидный результат, поскольку работает с числовым таймстампом, но может стать невалидным при NaN или Infinity:

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

fromJSDate

const jsDate = new Date("invalid");

const c = DateTime.fromJSDate(jsDate);

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

Если исходный объект Date некорректен, Luxon фиксирует это состояние.

fromFormat

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

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

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


Проверка временных интервалов Interval

Объект Interval представляет собой диапазон между двумя DateTime и требует строгой валидации обеих границ.

import { Interval, DateTime } from "luxon";

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

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

console.log(interval.isValid);

Если хотя бы один из концов интервала невалиден, весь Interval становится невалидным.

const badInterval = Interval.fromDateTimes(
  DateTime.invalid("error"),
  end
);

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

Дополнительно важно учитывать логическую корректность:

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

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

Интервалы с отрицательной длиной считаются недопустимыми.


Проверка Duration

Duration описывает продолжительность и также имеет встроенную систему валидации.

import { Duration } from "luxon";

const d1 = Duration.fromObject({ hours: 2, minutes: 30 });

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

Некорректные значения приводят к invalid состоянию:

const d2 = Duration.fromObject({ hours: NaN });

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

Особое внимание требуется при преобразовании из строк:

const d3 = Duration.fromISO("P2H30M");

console.log(d3.isValid);

ISO-формат должен строго соответствовать спецификации, иначе объект становится невалидным.


Проверка временных зон

Работа с часовыми поясами является критическим элементом валидации, особенно при использовании пользовательского ввода.

Luxon предоставляет объект IANAZone для проверки зоны:

import { IANAZone } from "luxon";

const zone = IANAZone.create("Europe/Paris");

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

Некорректные зоны:

const badZone = IANAZone.create("Mars/Phobos");

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

При использовании в DateTime зона также влияет на валидность вычислений:

const dt = DateTime.now().setZone("Invalid/Zone");

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

Системные методы проверки состояния

Для унифицированной обработки всех типов объектов Luxon применяется подход проверки через общий паттерн:

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

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


Сравнение дат как способ косвенной проверки

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

Метод equals позволяет сравнивать точные значения:

const a = DateTime.fromISO("2024-01-01T00:00");
const b = DateTime.fromISO("2024-01-01T00:00");

console.log(a.equals(b)); // true

Метод hasSame проверяет совпадение по уровню точности:

a.hasSame(b, "day");

Дополнительно применяется diff для анализа расхождений:

const diff = a.diff(b, "hours").hours;

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


Защитные проверки входных данных

При построении функций, использующих Luxon, важно учитывать не только валидность результата, но и валидность входных параметров.

Типовой шаблон защиты:

function parseDate(input) {
  if (!input) return null;

  const dt = DateTime.fromISO(input);

  if (!dt.isValid) return null;

  return dt;
}

Расширенный вариант с диагностикой:

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

  if (!dt.isValid) {
    return {
      error: dt.invalidReason,
      message: dt.invalidExplanation
    };
  }

  return dt;
}

Проверка наличия компонентов времени

Некоторые функции требуют проверки наличия конкретных единиц измерения в Duration или DateTime.

Для Duration:

const d = Duration.fromObject({ minutes: 45 });

console.log(d.hours); // 0
console.log(d.minutes); // 45

Отсутствующие единицы не вызывают ошибку, но требуют явной проверки при логике вычислений:

if (d.as("hours") < 1) {
  // обработка коротких интервалов
}

Работа с невалидными состояниями как часть логики

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

Типовой шаблон обработки цепочек:

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

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

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

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

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