UTC

В библиотеке Luxon работа с UTC рассматривается как базовый механизм нормализации времени для хранения, передачи и вычислений. UTC (Coordinated Universal Time) представляет собой эталонную временную шкалу, не зависящую от часовых поясов и переходов на летнее время, что делает её ключевым инструментом для серверных приложений, распределённых систем и API-интеграций.


Создание объектов времени в UTC

Основной способ создания времени в UTC — использование статического метода:

import { DateTime } from "luxon";

const dt = DateTime.utc();

Этот вызов возвращает объект DateTime, уже привязанный к нулевому смещению (+00:00).

При необходимости можно задать конкретные компоненты даты и времени:

const dt = DateTime.utc(2026, 5, 23, 14, 30);

Параметры передаются в порядке:

  • год
  • месяц
  • день
  • час
  • минута
  • секунда
  • миллисекунда

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


Преобразование локального времени в UTC

Любой локальный DateTime можно преобразовать в UTC с помощью метода toUTC():

const local = DateTime.local(2026, 5, 23, 14, 30);
const utc = local.toUTC();

Поведение метода заключается в сохранении абсолютного момента времени, но изменении представления в нулевой зоне.

Важно различать:

  • момент времени (timestamp) — абсолютная точка на временной шкале
  • представление времени (zone) — способ отображения этого момента

Явное задание зоны UTC при парсинге

При разборе строкового представления времени можно сразу указать зону:

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

Метод setZone позволяет изменить отображаемую временную зону без изменения момента времени:

const dt = DateTime.fromISO("2026-05-23T14:30:00+03:00");

const utcView = dt.setZone("utc");

По умолчанию Luxon сохраняет абсолютное время и пересчитывает компоненты даты и времени под новую зону.

Ключевой момент: setZone не изменяет timestamp, а только интерпретацию.


Получение текущего UTC времени

Для получения текущего времени в UTC используется:

const now = DateTime.utc();

Альтернативный эквивалент:

const now = DateTime.local().toUTC();

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


Форматирование UTC времени

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");

Работа с timestamp и UTC

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 и локальной зоной

Типичный сценарий — хранение времени в 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

Использование UTC в качестве единого формата хранения устраняет ряд проблем:

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

Типовой подход:

const event = {
  createdAt: DateTime.utc().toISO()
};

При чтении:

const dt = DateTime.fromISO(event.createdAt, { zone: "utc" });

Сравнение дат в 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-строками и UTC-индикацией

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 учитывать входную зону строки, а затем производится явное преобразование.


Частые ошибки при работе с UTC

Потеря зоны при форматировании

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

Здесь отсутствует информация о UTC, что может привести к неоднозначности.


Неверная интерпретация локального времени как UTC

DateTime.fromISO("2026-05-23T14:30:00", { zone: "utc" });

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


Использование локального Date без нормализации

new Date();

При передаче в Luxon без указания зоны возможно расхождение интерпретации:

DateTime.fromJSDate(new Date(), { zone: "utc" });

Поведение UTC относительно переходов времени

UTC не подвержен переходам на летнее или зимнее время. Это означает:

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

В отличие от локальных зон, где одно и то же время может существовать дважды или не существовать вовсе, UTC всегда линейна.


Интеграция UTC в архитектуру приложений

В типовой архитектуре:

  • клиент отправляет локальное время или ISO с зоной
  • сервер нормализует всё в UTC
  • база данных хранит UTC
  • API возвращает UTC или локализованное значение

Пример серверной обработки:

const received = DateTime.fromISO(payload.time, { setZone: true }).toUTC();

db.save({
  time: received.toISO()
});

Атомарность времени в UTC

Любая операция в UTC опирается на неизменяемый момент времени. Это позволяет:

  • корректно строить временные ряды
  • синхронизировать события между системами
  • обеспечивать детерминированность вычислений

Luxon при этом сохраняет иммутабельность объектов:

const a = DateTime.utc();
const b = a.setZone("local");

a === b; // false

Каждое преобразование возвращает новый объект, не изменяя исходный.