Основы работы с временными зонами

Библиотека Moment.js предоставляет гибкие инструменты для работы с датами и временем, включая поддержку временных зон. Основной модуль Moment.js не содержит встроенной поддержки временных зон за пределами локального времени и UTC, поэтому для полноценной работы используется дополнительная библиотека moment-timezone.


Подключение moment-timezone

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

const moment = require('moment-timezone');

После подключения доступны функции для создания объектов Moment с учётом конкретной временной зоны и для преобразования между зонами.


Создание даты с временной зоной

Создание даты в конкретной временной зоне выполняется с помощью метода tz:

let m = moment.tz("2026-05-21 12:00", "Europe/Moscow");

В этом примере объект m хранит дату и время в московской временной зоне. Важно понимать, что объект Moment всегда содержит момент во времени в UTC, а временная зона определяет, как эта дата отображается пользователю.


Преобразование между временными зонами

С помощью метода tz можно переводить дату из одной временной зоны в другую:

let m = moment.tz("2026-05-21 12:00", "Europe/Moscow");
let mNY = m.clone().tz("America/New_York");

Метод clone() используется для создания копии объекта, чтобы исходная дата осталась неизменной. После преобразования mNY.format() отобразит локальное время в Нью-Йорке.


Получение информации о временной зоне

Moment.js позволяет получать смещение временной зоны относительно UTC и название текущей зоны:

let m = moment.tz("2026-05-21 12:00", "Europe/Moscow");

console.log(m.format());            // 2026-05-21T12:00:00+03:00
console.log(m.utcOffset());         // 180 (минуты)
console.log(m.tz());                // Europe/Moscow
  • utcOffset() возвращает смещение в минутах. Положительное значение означает зоны восточнее UTC.
  • Метод tz() без аргументов возвращает идентификатор временной зоны.

Сравнение дат в разных временных зонах

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

let mMoscow = moment.tz("2026-05-21 12:00", "Europe/Moscow");
let mNY = moment.tz("2026-05-21 05:00", "America/New_York");

console.log(mMoscow.isSame(mNY)); // true

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


Перевод между локальным временем и UTC

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

let mLocal = moment.tz("2026-05-21 12:00", "Europe/Moscow");
let mUtc = mLocal.clone().utc();

console.log(mUtc.format()); // 2026-05-21T09:00:00Z

Метод utc() возвращает объект Moment в UTC. Важное различие: mLocal.format() и mUtc.format() покажут разные строки, хотя момент времени одинаков.


Работа с временными зонами при парсинге и форматировании

Moment.js позволяет парсить строки с указанием временной зоны и форматировать дату с выводом смещения:

let m = moment.tz("2026-05-21 12:00 +03:00", "YYYY-MM-DD HH:mm Z", "Europe/Moscow");

console.log(m.format("YYYY-MM-DD HH:mm z")); // 2026-05-21 12:00 MSK
console.log(m.format("YYYY-MM-DD HH:mm Z")); // 2026-05-21 12:00 +03:00
  • Формат z выводит сокращённое название зоны (MSK, EST, PST).
  • Формат Z показывает смещение относительно UTC.

Список доступных временных зон

Moment-timezone включает все общепринятые временные зоны IANA. Список доступных зон можно получить так:

console.log(moment.tz.names());

Это возвращает массив строк, например: "Europe/Moscow", "America/New_York", "Asia/Tokyo". Для корректной работы преобразований важно использовать именно эти идентификаторы.


Работа с переходами на летнее и зимнее время

Moment.js учитывает DST (Daylight Saving Time) автоматически при использовании moment-timezone:

let mWinter = moment.tz("2026-11-01 12:00", "Europe/Moscow");
let mSummer = moment.tz("2026-06-01 12:00", "Europe/Moscow");

console.log(mWinter.utcOffset()); // 180
console.log(mSummer.utcOffset()); // 180 (Москва не использует DST, но для зон с DST значения меняются)

При сравнении или вычислении разницы дат в зонах с DST смещения будут учтены автоматически:

let diff = mSummer.diff(mWinter, 'hours');
console.log(diff); // учитывает фактическую разницу часов

Практические рекомендации

  • Для хранения дат в базе данных лучше использовать UTC, а локальное время вычислять при отображении.
  • Всегда использовать clone() при преобразовании даты в другую временную зону, чтобы не менять исходный объект.
  • При работе с пользователями из разных стран использовать идентификаторы IANA вместо локальных смещений (+03:00), чтобы корректно учитывать DST.
  • Для парсинга и форматирования строк с датой и временем использовать методы moment.tz() с указанием формата и временной зоны.

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