В библиотеке Luxon работа с UTC рассматривается как базовый механизм нормализации времени для хранения, передачи и вычислений. UTC (Coordinated Universal Time) представляет собой эталонную временную шкалу, не зависящую от часовых поясов и переходов на летнее время, что делает её ключевым инструментом для серверных приложений, распределённых систем и API-интеграций.
Основной способ создания времени в UTC — использование статического метода:
import { DateTime } from "luxon";
const dt = DateTime.utc();
Этот вызов возвращает объект DateTime, уже привязанный к
нулевому смещению (+00:00).
При необходимости можно задать конкретные компоненты даты и времени:
const dt = DateTime.utc(2026, 5, 23, 14, 30);
Параметры передаются в порядке:
Результат всегда интерпретируется как UTC-время, без учета локальной временной зоны среды выполнения.
Любой локальный DateTime можно преобразовать в UTC с
помощью метода toUTC():
const local = DateTime.local(2026, 5, 23, 14, 30);
const utc = local.toUTC();
Поведение метода заключается в сохранении абсолютного момента времени, но изменении представления в нулевой зоне.
Важно различать:
При разборе строкового представления времени можно сразу указать зону:
const dt = DateTime.fromISO("2026-05-23T14:30:00", { zone: "utc" });
Если строка не содержит смещения, Luxon применяет указанную зону. Это критично для корректной интерпретации данных, приходящих из внешних источников.
При наличии явного смещения в ISO-строке Luxon автоматически учитывает его:
const dt = DateTime.fromISO("2026-05-23T14:30:00+03:00");
Внутренне это значение будет нормализовано к UTC при необходимости преобразования.
Метод setZone позволяет изменить отображаемую временную
зону без изменения момента времени:
const dt = DateTime.fromISO("2026-05-23T14:30:00+03:00");
const utcView = dt.setZone("utc");
По умолчанию Luxon сохраняет абсолютное время и пересчитывает компоненты даты и времени под новую зону.
Ключевой момент: setZone не изменяет timestamp, а только
интерпретацию.
Для получения текущего времени в UTC используется:
const now = DateTime.utc();
Альтернативный эквивалент:
const now = DateTime.local().toUTC();
Первый вариант предпочтительнее с точки зрения читаемости и производительности.
Luxon предоставляет гибкие способы форматирования:
const dt = DateTime.utc(2026, 5, 23, 14, 30);
dt.toISO(); // "2026-05-23T14:30:00.000Z"
dt.toISODate(); // "2026-05-23"
dt.toISOTime(); // "14:30:00.000Z"
Суффикс Z обозначает нулевое смещение и подтверждает
использование UTC.
Дополнительно возможно кастомное форматирование:
dt.toFormat("yyyy-MM-dd HH:mm:ss");
Результат не содержит информации о зоне, если не включить её явно:
dt.toFormat("yyyy-MM-dd HH:mm:ss ZZZZ");
UTC тесно связан с Unix timestamp — количеством миллисекунд с 1970-01-01T00:00:00Z.
Получение timestamp:
const dt = DateTime.utc(2026, 5, 23, 14, 30);
const ms = dt.toMillis();
Создание из timestamp:
const dt = DateTime.fromMillis(1716474600000, { zone: "utc" });
Если зона не указана, Luxon использует локальную временную зону среды выполнения, что может привести к несоответствиям при интерпретации данных.
Типичный сценарий — хранение времени в UTC и отображение в локальной зоне пользователя:
const utc = DateTime.utc(2026, 5, 23, 14, 30);
const local = utc.setZone("local");
Обратная операция:
const local = DateTime.local(2026, 5, 23, 14, 30);
const utc = local.toUTC();
Luxon гарантирует сохранение момента времени при таких преобразованиях.
Использование UTC в качестве единого формата хранения устраняет ряд проблем:
Типовой подход:
const event = {
createdAt: DateTime.utc().toISO()
};
При чтении:
const dt = DateTime.fromISO(event.createdAt, { zone: "utc" });
Сравнение DateTime объектов корректно работает только при одинаковой зоне или после нормализации:
const a = DateTime.utc(2026, 5, 23, 10, 0);
const b = DateTime.utc(2026, 5, 23, 12, 0);
a < b; // true
При смешанных зонах требуется нормализация:
const a = DateTime.local().toUTC();
const b = DateTime.fromISO("2026-05-23T12:00:00+02:00").toUTC();
a.equals(b);
ISO-формат является стандартом обмена временем:
const dt = DateTime.utc(2026, 5, 23, 14, 30);
const iso = dt.toISO();
Результат:
2026-05-23T14:30:00.000Z
При разборе:
const parsed = DateTime.fromISO(iso);
Luxon автоматически распознаёт Z как UTC-зону.
В системах, где источник данных может быть неоднородным, используется принудительная нормализация:
function normalizeToUTC(input) {
return DateTime.fromISO(input, { setZone: true }).toUTC();
}
Параметр setZone: true указывает Luxon учитывать входную
зону строки, а затем производится явное преобразование.
dt.toFormat("yyyy-MM-dd HH:mm:ss");
Здесь отсутствует информация о UTC, что может привести к неоднозначности.
DateTime.fromISO("2026-05-23T14:30:00", { zone: "utc" });
Если исходное время было локальным, такой код смещает момент времени.
new Date();
При передаче в Luxon без указания зоны возможно расхождение интерпретации:
DateTime.fromJSDate(new Date(), { zone: "utc" });
UTC не подвержен переходам на летнее или зимнее время. Это означает:
В отличие от локальных зон, где одно и то же время может существовать дважды или не существовать вовсе, UTC всегда линейна.
В типовой архитектуре:
Пример серверной обработки:
const received = DateTime.fromISO(payload.time, { setZone: true }).toUTC();
db.save({
time: received.toISO()
});
Любая операция в UTC опирается на неизменяемый момент времени. Это позволяет:
Luxon при этом сохраняет иммутабельность объектов:
const a = DateTime.utc();
const b = a.setZone("local");
a === b; // false
Каждое преобразование возвращает новый объект, не изменяя исходный.