Особенности UTC-операций

Day.js изначально оперирует локальным временем окружения JavaScript, однако работа с UTC требует явного подключения плагина и изменения режима интерпретации даты. Это принципиально важное поведение: библиотека не скрывает разницу между локальными и универсальными временными зонами, а делает её управляемой через API.

Подключение UTC-плагина

Функциональность UTC не входит в ядро Day.js и активируется через расширение:

import dayjs from 'dayjs'
import utc from 'dayjs/plugin/utc'

dayjs.extend(utc)

После расширения экземпляры Day.js получают дополнительный режим интерпретации времени, при котором все операции могут выполняться в UTC-контексте.

Инициализация даты в UTC

Создание даты в UTC-режиме отличается от стандартного поведения:

dayjs.utc()
dayjs.utc('2026-01-01T12:00:00')
dayjs.utc(1700000000000)

Во всех случаях объект интерпретируется как UTC-время, а не как локальное время системы.

Ключевое свойство:

  • входные данные трактуются как универсальное время
  • внутреннее представление также остаётся в UTC

Отличие utc() от локального режима

Без использования UTC-плагина:

dayjs('2026-01-01T12:00:00')

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

С UTC:

dayjs.utc('2026-01-01T12:00:00')

значение фиксируется как универсальное время без смещения.

Разница проявляется при форматировании:

dayjs('2026-01-01T12:00:00').format()      // локальное время
dayjs.utc('2026-01-01T12:00:00').format()  // UTC-время

Конвертация между UTC и локальным временем

Day.js позволяет переключаться между режимами представления даты без изменения исходного значения.

const d = dayjs.utc('2026-01-01T12:00:00')

d.local()

Метод local() переводит объект в локальную временную зону окружения, при этом исходная временная метка сохраняется.

Обратное преобразование:

dayjs('2026-01-01T12:00:00').utc()

Форматирование UTC-значений

Форматирование в UTC-режиме не требует дополнительных параметров:

dayjs.utc('2026-01-01T12:00:00').format('YYYY-MM-DD HH:mm:ss')

Важно учитывать, что форматирование не изменяет временную зону, оно лишь отображает текущее внутреннее состояние объекта.

Для явного вывода UTC-суффикса часто используется:

dayjs.utc().format('YYYY-MM-DDTHH:mm:ss[Z]')

Символ Z не добавляется автоматически, его необходимо задавать вручную.

Парсинг ISO-строк с UTC

ISO-формат с указанием Z автоматически интерпретируется как UTC:

dayjs('2026-01-01T12:00:00Z')

При наличии смещения:

dayjs('2026-01-01T12:00:00+03:00')

Day.js конвертирует значение в внутреннее представление времени, учитывая сдвиг.

При использовании utc() поведение становится фиксированным:

dayjs.utc('2026-01-01T12:00:00+03:00')

Смещение игнорируется, значение трактуется как чистое UTC-время.

Арифметика дат в UTC

Все операции добавления и вычитания выполняются в рамках текущего режима объекта.

dayjs.utc('2026-01-01T00:00:00')
  .add(1, 'day')

Результат остаётся в UTC-контексте без влияния локальной зоны.

Аналогично:

dayjs.utc('2026-01-01T00:00:00')
  .subtract(2, 'hours')

UTC-режим гарантирует отсутствие переходов между временными зонами.

Сравнение дат в UTC

Сравнение осуществляется на основе временной метки:

const a = dayjs.utc('2026-01-01T10:00:00')
const b = dayjs.utc('2026-01-01T12:00:00')

a.isBefore(b)
a.isAfter(b)

Так как обе даты нормализованы к UTC, результат не зависит от локальной системы.

Разница между датами (diff) в UTC

Метод diff в UTC-режиме оперирует абсолютным временем:

const a = dayjs.utc('2026-01-01T10:00:00')
const b = dayjs.utc('2026-01-01T12:00:00')

b.diff(a, 'hour')

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

Начало и конец интервалов

UTC-режим влияет на вычисление границ периода:

dayjs.utc('2026-01-15T12:34:00').startOf('day')
dayjs.utc('2026-01-15T12:34:00').endOf('day')

Границы дня определяются в рамках UTC-суток, а не локальных календарных суток.

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

Сериализация и JSON-представление

При сериализации Day.js в UTC-режиме сохраняется ISO-строка:

JSON.stringify(dayjs.utc('2026-01-01T12:00:00'))

Результат соответствует ISO 8601 с UTC-обозначением, если форматирование задано соответствующим образом.

Явное управление:

dayjs.utc().toISOString()

Взаимодействие UTC с форматами времени

UTC-режим влияет только на интерпретацию и хранение времени, но не ограничивает использование форматов:

dayjs.utc('2026-01-01T12:00:00').format('DD.MM.YYYY HH:mm')

или

dayjs.utc('2026-01-01').format('YYYY/MM/DD')

Форматы остаются универсальными, но базируются на UTC-значении.

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

Несовпадение локального и UTC-представления возникает при смешивании режимов:

dayjs('2026-01-01T12:00:00').utc().format()

и

dayjs.utc('2026-01-01T12:00:00').local().format()

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

Ещё одна типичная проблема — повторное применение utc():

dayjs.utc(dayjs.utc('2026-01-01'))

Вторичное оборачивание не изменяет результат, но может создавать логическую неоднозначность в коде.

Согласованность UTC в серверных приложениях

Использование UTC в Day.js обеспечивает стабильность при распределённых системах, где серверы могут находиться в разных временных зонах. Все временные операции приводятся к единой шкале времени, что устраняет необходимость учитывать локальные настройки окружения при вычислениях, сравнении и хранении дат.