Библиотека Day.js по умолчанию работает с локальным часовым поясом среды выполнения. Для корректного сравнения дат между регионами требуется подключение дополнительных плагинов:
utctimezoneimport dayjs from 'dayjs'
import utc from 'dayjs/plugin/utc'
import timezone from 'dayjs/plugin/timezone'
dayjs.extend(utc)
dayjs.extend(timezone)
Плагин utc добавляет поддержку времени UTC, а
timezone позволяет работать с часовыми поясами IANA:
'Europe/Moscow'
'Asia/Almaty'
'America/New_York'
'Europe/Berlin'
Одинаковое локальное время в разных странах представляет разные реальные моменты времени.
Пример:
const moscow = dayjs.tz('2025-05-10 12:00', 'Europe/Moscow')
const newYork = dayjs.tz('2025-05-10 12:00', 'America/New_York')
Обе даты отображают 12:00, но фактически между ними
несколько часов разницы.
Проверка:
console.log(moscow.toISOString())
console.log(newYork.toISOString())
Результат:
2025-05-10T09:00:00.000Z
2025-05-10T16:00:00.000Z
Day.js сравнивает именно абсолютные временные метки, а не строковое отображение времени.
isBeforeМетод isBefore() определяет, произошла ли одна дата
раньше другой.
const first = dayjs.tz('2025-01-01 10:00', 'Europe/Moscow')
const second = dayjs.tz('2025-01-01 10:00', 'Asia/Tokyo')
console.log(first.isBefore(second))
Несмотря на одинаковое локальное время, результат будет зависеть от фактического UTC-времени.
Day.js приводит обе даты к Unix Timestamp:
console.log(first.valueOf())
console.log(second.valueOf())
Сравнение выполняется именно по миллисекундам.
isAfterconst london = dayjs.tz('2025-06-01 08:00', 'Europe/London')
const paris = dayjs.tz('2025-06-01 08:00', 'Europe/Paris')
console.log(london.isAfter(paris))
Поскольку Париж находится в другом часовом поясе, одинаковое локальное время соответствует различным UTC-моментам.
isSameconst utcDate = dayjs.utc('2025-01-01T12:00:00Z')
const localDate = dayjs.tz(
'2025-01-01 15:00',
'Europe/Moscow'
)
console.log(utcDate.isSame(localDate))
Результат:
true
Хотя локальное представление отличается, обе даты описывают один и тот же момент времени.
Методы сравнения поддерживают второй аргумент — единицу измерения.
date1.isSame(date2, 'day')
date1.isBefore(date2, 'month')
date1.isAfter(date2, 'year')
Пример:
const berlin = dayjs.tz(
'2025-07-01 23:30',
'Europe/Berlin'
)
const tokyo = dayjs.tz(
'2025-07-02 06:30',
'Asia/Tokyo'
)
console.log(berlin.isSame(tokyo, 'day'))
Результат зависит от локального календарного дня каждой даты.
Наиболее безопасный способ сравнения — перевод обеих дат в UTC.
const a = dayjs.tz(
'2025-03-10 15:00',
'America/New_York'
).utc()
const b = dayjs.tz(
'2025-03-10 21:00',
'Europe/Moscow'
).utc()
console.log(a.isSame(b))
Такой подход особенно важен:
utc() и
tz()utc()Переводит дату в UTC.
const date = dayjs().utc()
tz()Создает дату в указанном часовом поясе.
const date = dayjs.tz(
'2025-01-01 12:00',
'Asia/Almaty'
)
const local = dayjs('2025-01-01 12:00')
const utc = dayjs.utc('2025-01-01 12:00')
console.log(local.isSame(utc))
Результат может быть false, потому что:
diff() с часовыми поясамиМетод diff() вычисляет разницу между датами.
const sydney = dayjs.tz(
'2025-05-01 10:00',
'Australia/Sydney'
)
const toronto = dayjs.tz(
'2025-04-30 20:00',
'America/Toronto'
)
console.log(sydney.diff(toronto, 'hour'))
Day.js автоматически учитывает смещения.
Одной из самых сложных проблем являются DST-переходы (Daylight Saving Time).
Пример:
const before = dayjs.tz(
'2025-03-30 01:30',
'Europe/Berlin'
)
const after = dayjs.tz(
'2025-03-30 03:30',
'Europe/Berlin'
)
console.log(after.diff(before, 'hour'))
В некоторых случаях результат будет отличаться от ожидаемого, потому что один час может быть пропущен.
Во время обратного перехода часов одинаковое локальное время может существовать дважды.
const ambiguous = dayjs.tz(
'2025-10-26 02:30',
'Europe/Berlin'
)
Такие ситуации особенно критичны:
Многие API возвращают даты в UTC:
{
"createdAt": "2025-05-01T12:00:00Z"
}
Правильная обработка:
const apiDate = dayjs.utc(data.createdAt)
const localDate = dayjs()
console.log(apiDate.isBefore(localDate))
const user1 = dayjs.tz(
'2025-08-01 09:00',
'Asia/Tokyo'
)
const user2 = dayjs.tz(
'2025-08-01 09:00',
'America/Chicago'
)
console.log(user1.isSame(user2))
Локальное время совпадает, но реальные моменты времени различаются.
const london = dayjs().tz('Europe/London')
const dubai = dayjs().tz('Asia/Dubai')
console.log(london.format())
console.log(dubai.format())
Сравнение:
console.log(london.isBefore(dubai))
dayjs.tz.setDefault('Europe/Moscow')
После этого:
const date = dayjs.tz('2025-01-01 10:00')
будет автоматически использовать указанный пояс.
Сброс:
dayjs.tz.setDefault()
Метод utcOffset() возвращает смещение в минутах.
const date = dayjs.tz(
'2025-01-01 12:00',
'Asia/Tokyo'
)
console.log(date.utcOffset())
Результат:
540
Иногда безопаснее сравнивать даты напрямую через миллисекунды.
const a = dayjs.tz(
'2025-01-01 12:00',
'Europe/Moscow'
)
const b = dayjs.tz(
'2025-01-01 08:00',
'UTC'
)
console.log(a.valueOf() === b.valueOf())
При передаче данных между сервером и клиентом рекомендуется использовать ISO 8601.
const iso = dayjs().toISOString()
Пример:
2025-05-22T10:15:00.000Z
Восстановление:
const parsed = dayjs(iso)
Неправильно:
'2025-01-01 10:00' > '2025-01-01 09:00'
Правильно:
dayjs(date1).isAfter(date2)
Неправильно:
const date = dayjs(apiDate)
Правильно:
const date = dayjs.utc(apiDate)
timezonedayjs.tz(...)
без подключения плагина вызовет ошибку.
const meetingUtc = dayjs.utc(
'2025-09-01T14:00:00Z'
)
const moscow = meetingUtc.tz('Europe/Moscow')
const tokyo = meetingUtc.tz('Asia/Tokyo')
const newYork = meetingUtc.tz('America/New_York')
console.log(moscow.format())
console.log(tokyo.format())
console.log(newYork.format())
Все пользователи видят локальное время, но событие остается единым.
const expiresAt = dayjs.utc(
'2025-12-31T23:59:59Z'
)
const now = dayjs.utc()
if (now.isAfter(expiresAt)) {
console.log('Срок истек')
}
UTC устраняет проблемы, связанные с региональными настройками.
const events = [
{
date: dayjs.tz(
'2025-05-01 10:00',
'Europe/Berlin'
)
},
{
date: dayjs.tz(
'2025-05-01 12:00',
'Asia/Tokyo'
)
}
]
const now = dayjs.utc()
const futureEvents = events.filter(event =>
event.date.utc().isAfter(now)
)
На сервере рекомендуется хранить даты:
Преобразование в локальный часовой пояс должно происходить только на этапе отображения.
dayjs.utc(date).tz(userTimezone)
Наиболее надежный подход:
date1.utc().isSame(date2.utc())
Большинство СУБД поддерживают UTC:
При чтении данных важно явно учитывать часовой пояс.
Day.js значительно легче многих альтернатив и хорошо подходит для клиентских приложений.
Особенно важно при:
При массовом сравнении дат желательно избегать повторных преобразований:
const normalized = date.utc()
normalized.isBefore(other)
normalized.isAfter(other)
Перед сравнением желательно убедиться, что дата корректна.
const date = dayjs(input)
console.log(date.isValid())
Некорректные даты могут привести к ошибкам логики сравнения.
Для расширенного сравнения часто используются:
import isSameOrAfter from 'dayjs/plugin/isSameOrAfter'
import isSameOrBefore from 'dayjs/plugin/isSameOrBefore'
import minMax from 'dayjs/plugin/minMax'
Пример:
dayjs.extend(isSameOrAfter)
date.isSameOrAfter(otherDate)
const start = dayjs.utc('2025-01-01')
const end = dayjs.utc('2025-12-31')
const target = dayjs.utc()
const isInside =
target.isAfter(start) &&
target.isBefore(end)
Иногда требуется сравнивать только часы и минуты.
const first = dayjs.tz(
'2025-01-01 09:30',
'Europe/Moscow'
)
const second = dayjs.tz(
'2025-07-10 09:30',
'Europe/Moscow'
)
console.log(
first.format('HH:mm') ===
second.format('HH:mm')
)
Такой подход подходит только для локального отображения и не отражает реальное UTC-время.