Day.js изначально работает с датами в локальной среде выполнения JavaScript. Это означает, что без дополнительных плагинов библиотека не выполняет полноценную конвертацию между временными зонами, а лишь оперирует объектом времени в текущем окружении (браузер или Node.js).
Для работы с часовыми поясами используется комбинация плагинов:
utc — переводит Day.js в универсальный координированный
формат времени (UTC)timezone — добавляет поддержку IANA-зон (например,
Europe/Berlin, Asia/Almaty)import dayjs from 'dayjs'
import utc from 'dayjs/plugin/utc'
import timezone from 'dayjs/plugin/timezone'
dayjs.extend(utc)
dayjs.extend(timezone)
После подключения этих расширений появляется возможность корректно преобразовывать даты между зонами, не теряя исходное абсолютное время.
Любая работа с часовыми поясами в Day.js опирается на концепцию UTC как нейтральной базы.
const nowUtc = dayjs().utc()
console.log(nowUtc.format())
Ключевой момент:
utc() не «переводит время», а интерпретирует текущий
момент как UTCЭто важно для избежания ошибок при работе с локальными датами, особенно в серверных приложениях.
При обработке пользовательского ввода часто возникает необходимость нормализовать дату в UTC.
const local = dayjs('2026-05-23 12:00')
const utcTime = local.utc()
console.log(utcTime.format())
Здесь происходит не изменение момента времени, а смена представления:
Типичная ошибка — считать, что utc() просто «меняет
метку». На самом деле происходит пересчёт временной оси.
Плагин timezone добавляет поддержку стандартизированных
зон:
const moscow = dayjs().tz('Europe/Moscow')
const tokyo = dayjs().tz('Asia/Tokyo')
console.log(moscow.format())
console.log(tokyo.format())
Особенности:
Основной сценарий — перевод одного и того же момента в разные зоны:
const base = dayjs.utc('2026-05-23T10:00:00Z')
const newYork = base.tz('America/New_York')
const london = base.tz('Europe/London')
console.log(newYork.format())
console.log(london.format())
Важно:
tz() меняет только отображение, не сам момент
времениИногда требуется интерпретировать локальную дату как принадлежащую конкретной зоне:
const input = dayjs('2026-05-23 10:00')
const asTokyo = input.tz('Asia/Tokyo', true)
Второй аргумент true означает:
Это критично при обработке данных из форм или API.
Отображение даты зависит от выбранной зоны:
const time = dayjs.utc('2026-05-23T10:00:00Z')
console.log(time.tz('Asia/Almaty').format('YYYY-MM-DD HH:mm'))
console.log(time.tz('America/Los_Angeles').format('YYYY-MM-DD HH:mm'))
Форматирование происходит после конвертации, поэтому:
Иногда требуется вычислить разницу относительно UTC:
const offset = dayjs().tz('Europe/Moscow').utcOffset()
console.log(offset)
Особенности:
Корректный паттерн конвертации:
const utcMoment = dayjs.utc('2026-05-23T10:00:00Z')
const zones = [
'Asia/Almaty',
'Europe/Berlin',
'America/New_York'
]
const converted = zones.map(zone => ({
zone,
time: utcMoment.tz(zone).format()
}))
Принцип:
// некорректно
const wrong = dayjs('2026-05-23T10:00:00Z').tz('Asia/Tokyo')
Проблема:
const a = dayjs('2026-05-23 10:00')
const b = a.tz('Europe/London').tz('Asia/Tokyo')
Ошибка:
Некоторые зоны изменяют смещение в течение года:
Europe/BerlinAmerica/New_YorkDay.js корректно учитывает это, но только при использовании IANA-зон:
dayjs.tz('2026-07-01', 'Europe/Berlin')
dayjs.tz('2026-01-01', 'Europe/Berlin')
Типичный сценарий серверной обработки:
const userInput = '2026-05-23 18:00'
const userZone = 'Asia/Almaty'
const normalized = dayjs.tz(userInput, userZone).utc()
Результат:
const storedUtc = dayjs.utc('2026-05-23T12:00:00Z')
function render(zone) {
return storedUtc.tz(zone).format('HH:mm')
}
render('Asia/Almaty')
render('America/New_York')
Такой подход обеспечивает:
const events = [
'2026-05-23T10:00:00Z',
'2026-05-23T12:00:00Z',
'2026-05-23T15:00:00Z'
]
const converted = events.map(e =>
dayjs.utc(e).tz('Asia/Almaty').format()
)
Принцип:
const a = dayjs.tz('2026-05-23T10:00:00Z', 'Asia/Almaty')
const b = dayjs.tz('2026-05-23T10:00:00Z', 'Europe/London')
console.log(a.valueOf() === b.valueOf())
Важно:
Рекомендуемая схема:
.toISOString())const stored = dayjs().utc().toISOString()
const restored = dayjs.utc(stored)
Такой подход исключает неоднозначность и ошибки при миграции между зонами.