Проверка корректности объектов 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);
}
Метод особенно чувствителен к календарным несоответствиям, например, несуществующим датам.
const b = DateTime.fromMillis(1710000000000);
if (b.isValid) {
console.log(b.toISO());
}
fromMillis почти всегда возвращает валидный результат, поскольку работает с числовым таймстампом, но может стать невалидным при NaN или Infinity:
DateTime.fromMillis(NaN).isValid; // false
const jsDate = new Date("invalid");
const c = DateTime.fromJSDate(jsDate);
console.log(c.isValid); // false
Если исходный объект Date некорректен, Luxon фиксирует это состояние.
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;
}
Такая модель предотвращает распространение скрытых ошибок и позволяет сохранять предсказуемость поведения функций, работающих с датами и временем.