Инструменты отладки

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

Ключевые свойства для диагностики:

  • isValid — булево значение, определяющее, корректен ли объект
  • invalidReason — краткое описание причины ошибки
  • invalidExplanation — более развернутое объяснение
import { DateTime } from "luxon";

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

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

При работе с потоками данных (API, формы, базы данных) проверка isValid должна рассматриваться как обязательный шаг, поскольку Luxon не выбрасывает исключения по умолчанию, а возвращает специальный объект с состоянием ошибки.

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

  • toISO() — позволяет увидеть, как библиотека интерпретировала входные данные
const dt = DateTime.fromISO("2024-05-24T25:61:00");

console.log(dt.toISO()); // null (если невалидно)
console.log(dt.toString()); // Invalid DateTime

Инспекция зон времени

Одна из наиболее сложных областей отладки в Luxon — работа с часовыми поясами. Ошибки часто возникают из-за неявного использования системной зоны или неправильного задания zone.

Основные методы и свойства:

  • zoneName — название текущей зоны
  • offset — смещение в минутах от UTC
  • toUTC() / setZone() — преобразования между зонами
const dt = DateTime.local();

console.log(dt.zoneName);
console.log(dt.offset);

Типичная ошибка — ожидание UTC-времени при использовании DateTime.local():

const dt = DateTime.local(2024, 5, 24, 10);
console.log(dt.toISO()); // локальное время, не UTC

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

const utc = dt.toUTC();
console.log(utc.toISO());

Или фиксировать зону:

const ny = dt.setZone("America/New_York");
console.log(ny.toString());

Если поведение отличается от ожидаемого, проверка zoneName почти всегда выявляет источник проблемы.


Диагностика парсинга входных данных

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

  • fromISO
  • fromRFC2822
  • fromFormat
  • fromMillis

Основная проблема — несоответствие формата входной строки и метода парсинга.

const dt = DateTime.fromFormat("24/05/2024", "yyyy-MM-dd");

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

В таких случаях полезно сравнивать:

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

Особое внимание требует fromFormat, так как он не бросает ошибок:

const dt = DateTime.fromFormat("2024-05-24", "dd/MM/yyyy");

console.log(dt.invalidReason); // mismatch

Для отладки сложных форматов удобно временно преобразовывать данные в ISO:

const dt = DateTime.fromFormat(input, format);

console.log(dt.toISO());

Если результат null, значит проблема в шаблоне или входных данных.


Отладка форматирования

Форматирование через toFormat() часто вызывает расхождения между ожидаемым и реальным результатом.

const dt = DateTime.local(2024, 5, 24, 18, 30);

console.log(dt.toFormat("yyyy-MM-dd HH:mm"));

При ошибках форматирования важно проверять:

  • корректность токенов Luxon
  • локаль (locale)
  • наличие нулевых значений

Полезные инструменты:

console.log(dt.locale);
console.log(dt.toObject());

Метод toObject() показывает внутреннюю структуру:

{
  year: 2024,
  month: 5,
  day: 24,
  hour: 18,
  minute: 30
}

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


Работа с эпохой и миллисекундами

При отладке часто требуется перейти к «сырому» представлению времени.

Основные методы:

  • toMillis() — количество миллисекунд с эпохи Unix
  • valueOf() — аналогичный числовой контекст
const dt = DateTime.local();

console.log(dt.toMillis());
console.log(+dt);

Типичная ошибка — сравнение объектов DateTime напрямую:

const a = DateTime.local();
const b = DateTime.local();

console.log(a === b); // false всегда

Корректный подход:

console.log(a.toMillis() === b.toMillis());

Также полезно отслеживать преобразования:

const utc = dt.toUTC();

console.log(dt.toMillis());
console.log(utc.toMillis());

Если значения неожиданно различаются — проблема почти всегда в зоне или DST.


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

Luxon не предназначен для прямого сравнения объектов через ===. Для диагностики используются:

  • toMillis()
  • diff()
  • equals()
const a = DateTime.local(2024, 5, 24);
const b = DateTime.local(2024, 5, 25);

console.log(a < b); // некорректно
console.log(a.toMillis() < b.toMillis()); // правильно

Метод diff() помогает анализировать разницу:

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

console.log(diff.days);

Для отладки временных интервалов это более информативно, чем ручное вычисление.


Логирование внутренних состояний

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

const dt = DateTime.fromISO(input)
  .setZone("utc")
  .plus({ days: 1 })
  .setLocale("ru");

console.log(dt.toString());

Метод toString() возвращает краткое представление, полезное для трассировки.

Дополнительно:

  • inspect() (через console.log) раскрывает объект в devtools
  • toISO() фиксирует стандартизированное представление
  • toFormat() помогает проверить локализованное отображение

Для цепочек преобразований эффективна стратегия пошагового логирования:

const step1 = DateTime.fromISO(input);
console.log("step1", step1.toISO());

const step2 = step1.setZone("utc");
console.log("step2", step2.toISO());

const step3 = step2.plus({ hours: 3 });
console.log("step3", step3.toISO());

Работа с невалидными объектами

Luxon не прерывает выполнение при ошибках, поэтому важно явно отслеживать состояние объекта.

const dt = DateTime.fromFormat("invalid-date", "yyyy-MM-dd");

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

В сложных системах это состояние часто теряется при передаче между функциями:

function process(dt) {
  return dt.plus({ days: 1 });
}

Если dt невалиден, ошибка не проявится сразу, а «расползётся» по цепочке. Поэтому проверка должна быть централизованной.


Отладка локалей и форматов отображения

Локаль влияет на:

  • названия месяцев
  • порядок элементов даты
  • форматирование времени
const dt = DateTime.local().setLocale("ru");

console.log(dt.toLocaleString(DateTime.DATE_FULL));

Для диагностики:

console.log(dt.locale);
console.log(dt.toFormat("MMMM"));

Если вывод неожиданен — проблема почти всегда в неустановленной или перезаписанной локали.


Типичные ошибки и их выявление

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

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

Выявляется через invalidReason: mismatch.


2. Потеря часового пояса

DateTime.fromISO("2024-05-24T10:00");

Без явной зоны интерпретируется как локальное время.

Диагностика:

console.log(dt.zoneName);

3. Сравнение объектов напрямую

a === b // всегда false

Решение — toMillis().


4. Неправильное ожидание UTC

DateTime.local().toISO();

Решение — toUTC().


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

const dt = DateTime.fromISO("bad");
dt.plus({ days: 1 }); // тихая ошибка

Правильная практика — проверка до любых операций.


6. Ошибки локали

setLocale("ru-RU") // иногда не совпадает с ожидаемым форматом

Диагностика через toFormat() и locale.