В приложениях, где используются временные данные, библиотека Luxon
предоставляет структуры DateTime, Duration и
Interval, которые существенно отличаются от стандартного
Date. При попадании таких объектов в систему логирования
возникают проблемы сериализации, потери контекста и неконсистентного
отображения в консоли и лог-файлах.
Объекты Luxon являются иммутабельными структурами,
содержащими внутреннее представление времени и метаданных локали,
таймзоны и формата. При прямом логировании через
console.log или при сериализации через
JSON.stringify поведение отличается от примитивных
типов.
Основная особенность заключается в том, что:
DateTime не является обычным объектом
DateПри выводе объекта Luxon в консоль происходит отображение служебной структуры, а не человекочитаемого времени:
import { DateTime } from "luxon";
const dt = DateTime.now();
console.log(dt);
Результат зависит от среды выполнения и обычно не является стабильным для логирования или анализа.
Для получения стабильного представления используются методы преобразования.
console.log(DateTime.now().toISO());
Метод toISO() формирует стандартную строку:
console.log(DateTime.now().toMillis());
Метод toMillis() возвращает UNIX-время в
миллисекундах.
Используется в случаях:
Альтернативой является:
DateTime.now().valueOf()
который возвращает тот же временной штамп.
При попытке сериализации объекта напрямую:
const dt = DateTime.now();
console.log(JSON.stringify({ time: dt }));
результатом становится:
{}
или потеря полезных данных.
Это связано с тем, что внутренние поля Luxon не перечисляемые.
const logEntry = {
event: "user_login",
time: DateTime.now().toISO()
};
console.log(JSON.stringify(logEntry));
Данный подход обеспечивает стабильность логов и их переносимость.
Luxon предоставляет метод toObject(), возвращающий
разложенное представление времени:
const dt = DateTime.now().toObject();
console.log(dt);
Результат:
{
year: 2026,
month: 5,
day: 24,
hour: 12,
minute: 30,
second: 15,
millisecond: 123
}
Такое представление полезно при:
Одной из ключевых особенностей Luxon является поддержка таймзон.
import { DateTime } from "luxon";
const dt = DateTime.now().setZone("Europe/Paris");
console.log(dt.toISO());
Для логов важно фиксировать:
Пример структурированного объекта:
const logEntry = {
event: "payment_received",
timeLocal: dt.toISO(),
timeUTC: dt.toUTC().toISO(),
zone: dt.zoneName
};
Объект Duration требует явного преобразования:
import { Duration } from "luxon";
const duration = Duration.fromObject({ minutes: 5 });
console.log(duration.toISO());
Результат:
PT5M
Для расширенного логирования:
console.log(duration.toObject());
import { DateTime, Interval } from "luxon";
const start = DateTime.now();
const end = start.plus({ hours: 2 });
const interval = Interval.fromDateTimes(start, end);
console.log(interval.toISO());
Результат:
2026-05-24T10:00:00.000Z/2026-05-24T12:00:00.000Z
Для систем логирования часто применяется кастомный replacer:
function luxonReplacer(key, value) {
if (value?.toISO) {
return value.toISO();
}
return value;
}
const logEntry = {
event: "session_start",
time: DateTime.now()
};
console.log(JSON.stringify(logEntry, luxonReplacer));
Такой подход обеспечивает:
В системах вроде Pino или Winston Luxon-объекты требуют нормализации перед передачей в логгер.
Пример подготовки записи:
import { DateTime } from "luxon";
const createLog = (event, meta = {}) => ({
event,
time: DateTime.now().toISO(),
meta
});
Использование:
logger.info(createLog("cache_miss", { key: "user:123" }));
JSON.stringify({ time: DateTime.now() });
Результат не содержит полезного значения.
Смешивание ISO, timestamp и объектов Luxon в одном логе приводит к:
Отсутствие явного указания зоны приводит к неоднозначности при распределенных системах.
Для логирования временных данных с Luxon используются три базовых формата:
toISO) — основной человекочитаемый
форматtoMillis) — для вычисленийtoObject) — для аналитикиКомбинация этих форматов обеспечивает совместимость между системами хранения и обработки логов.