- Home »

Понимание работы с датой и временем в JavaScript
Дата и время в JavaScript — тема, которая кажется банальной, пока не сталкиваешься с реальными задачами: логирование событий на сервере, автоматизация бэкапов, синхронизация времени между сервисами, работа с таймзонами, планирование задач по расписанию. Если ты хоть раз пытался понять, почему твой скрипт запускается не тогда, когда надо, или почему логи с разных серверов невозможно свести в одну хронологию — эта статья для тебя. Здесь разберём, как JavaScript работает с датой и временем, как быстро и просто всё настроить, какие грабли поджидают, и как их обойти. Будет много практики, примеры, схемы, советы, а ещё — немного гиковских лайфхаков для автоматизации и серверных скриптов.
Как это работает: основы Date в JavaScript
В JavaScript есть встроенный объект Date
, который отвечает за всё, что связано с датой и временем. Он работает одинаково как в браузере, так и в Node.js (а значит — и на сервере). Но вот нюанс: вся работа с датой и временем в JS — это всегда UTC внутри, а вот отображение и парсинг по умолчанию — в локальной таймзоне. Это уже первый источник боли для тех, кто пишет серверные скрипты.
- Внутри
Date
хранит количество миллисекунд с 1 января 1970 года по UTC (эпоха Unix). - Методы
getHours()
,getDate()
и т.д. возвращают локальное время сервера (или клиента). - Методы
getUTCHours()
,getUTCDate()
— возвращают время по UTC. - Парсинг строки без указания таймзоны — всегда локальное время.
- Парсинг строки с
Z
или смещением (+03:00
) — по UTC или указанной зоне.
Вот базовый пример:
const now = new Date(); // текущее локальное время сервера
console.log(now.toString()); // Локальное время
console.log(now.toISOString()); // UTC в ISO формате
console.log(now.getTime()); // миллисекунды с эпохи Unix
console.log(now.getHours(), now.getUTCHours()); // локальный час, UTC-час
Всё просто? На первый взгляд — да. Но если ты работаешь с несколькими серверами в разных таймзонах, или твой сервер крутится в UTC, а пользователи — в Москве, Нью-Йорке и Токио, то начинается веселье.
Как быстро и просто всё настроить: практические советы
Вот чеклист, который реально экономит часы жизни:
- Всегда храни дату и время в UTC. Для логов, БД, файлов — только UTC. Локальное время — только для отображения.
- Используй ISO 8601 формат (
YYYY-MM-DDTHH:mm:ss.sssZ
). Его понимают все языки и базы данных. - Для парсинга и форматирования используй проверенные библиотеки — moment.js (устарел, но всё ещё популярен), date-fns, luxon, Temporal API (будущее JS, но уже можно использовать через полифиллы).
- Проверяй таймзону сервера:
date
в консоли,process.env.TZ
в Node.js. - Для cron-скриптов всегда указывай таймзону явно (например, через переменную окружения
TZ=UTC
).
Пример настройки таймзоны в Node.js:
process.env.TZ = 'UTC'; // все новые Date будут в UTC
const now = new Date();
console.log(now.toISOString()); // всегда UTC
Для запуска скрипта с нужной таймзоной:
TZ=Europe/Moscow node myscript.js
Если используешь cron на сервере — указывай таймзону в crontab:
CRON_TZ=Europe/Moscow
0 3 * * * node /path/to/backup.js
Примеры, схемы, практические советы
Давай разберём типовые кейсы — и где чаще всего наступают на грабли.
Кейс | Что делают новички | Что делать правильно | Почему |
---|---|---|---|
Логирование времени события | console.log(new Date()) | console.log(new Date().toISOString()) | ISO-формат всегда в UTC, легко парсить и сравнивать |
Сравнение дат | date1 > date2 | date1.getTime() > date2.getTime() | Сравнивать всегда по миллисекундам, а не по строкам |
Парсинг даты из строки | new Date(‘2024-06-01 12:00:00’) | new Date(‘2024-06-01T12:00:00Z’) | Без “T” и “Z” — локальное время, с “T” и “Z” — UTC |
Планирование задач | cron без TZ | cron с CRON_TZ или TZ в окружении | Иначе задача сдвинется при смене таймзоны или DST |
Ещё один частый вопрос — как быстро получить дату в нужной таймзоне? В стандартном Date
это неудобно, поэтому вот пример с date-fns-tz:
const { zonedTimeToUtc, utcToZonedTime, format } = require('date-fns-tz');
const date = new Date();
const moscow = utcToZonedTime(date, 'Europe/Moscow');
console.log(format(moscow, 'yyyy-MM-dd HH:mm:ssXXX', { timeZone: 'Europe/Moscow' }));
Всё, теперь ты можешь выводить время в любой зоне, не парясь о смещениях.
Положительные и отрицательные кейсы
- Положительный: Хранишь все даты в UTC, используешь ISO-формат, в логах всегда точное время, легко дебажить и сводить логи с разных серверов.
- Отрицательный: Хранишь локальное время, не указываешь таймзону, после перевода часов cron-скрипты запускаются не тогда, когда надо, логи не сходятся, пользователи жалуются на “странные” даты.
Рекомендация: всегда явно указывай таймзону, когда работаешь с датой и временем. Не доверяй “по умолчанию”.
Команды и утилиты для работы с датой и временем
Вот список must-have команд и npm-пакетов для автоматизации:
date
— узнать текущее время и таймзону на сервереtimedatectl
— управление таймзоной в Linuxntpdate
илиchrony
— синхронизация времениnpm install date-fns date-fns-tz
— современная библиотека для датnpm install luxon
— мощная альтернатива moment.jsnpm install moment moment-timezone
— если нужен старый добрый moment
Пример синхронизации времени на сервере (Linux):
sudo apt install ntpdate
sudo ntpdate pool.ntp.org
Проверить таймзону:
date
timedatectl
Установить таймзону:
sudo timedatectl set-timezone Europe/Moscow
Сравнение популярных JS-библиотек для работы с датой и временем
Библиотека | Плюсы | Минусы | Когда использовать |
---|---|---|---|
moment.js | Простота, много туториалов, поддержка таймзон | Большой размер, устарел, не развивается | Легаси-проекты, быстрые скрипты |
date-fns | Модульность, современный синтаксис, малый размер | Требует установки доп. пакета для таймзон | Новые проекты, серверные скрипты |
luxon | Мощная работа с таймзонами, поддержка ISO, Duration | Чуть сложнее API, чуть больше размер | Сложные задачи, автоматизация, планирование |
Temporal API | Будущее JS, встроено в язык (скоро), поддержка всех кейсов | Пока в стадии proposal, нужен полифилл | Эксперименты, подготовка к будущему |
Интересные факты и нестандартные способы использования
- В JS можно создать дату до 1970 года и даже до нашей эры:
new Date(-62167219200000)
— это 1 января 0001 года. - Миллисекунды можно использовать для генерации уникальных ID:
Date.now().toString(36)
. - В Node.js можно использовать
process.hrtime()
для измерения времени выполнения с точностью до наносекунд. - Для автоматизации бэкапов удобно использовать дату в имени файла:
backup-$(date +%Y-%m-%dT%H-%M-%S).tar.gz
. - Можно синхронизировать время между контейнерами Docker через общий NTP-сервер.
Новые возможности и автоматизация
С появлением Temporal API (уже можно использовать через полифилл), работа с датой и временем в JS станет проще и надёжнее. Теперь можно:
- Создавать даты и интервалы без багов с таймзонами и DST.
- Планировать задачи по расписанию с учётом перехода на летнее/зимнее время.
- Сравнивать даты в разных таймзонах без ручных вычислений.
- Автоматизировать отчёты, бэкапы, логи с учётом времени в разных регионах.
Пример с Temporal (через полифилл):
const { Temporal } = require('@js-temporal/polyfill');
const now = Temporal.Now.zonedDateTimeISO('Europe/Moscow');
console.log(now.toString());
Выводы и рекомендации
Работа с датой и временем в JavaScript — это не только про отображение часов на сайте. Это про надёжность логов, корректную работу автоматизации, синхронизацию между сервисами и серверами. Если хочешь, чтобы твои скрипты работали предсказуемо, а логи не превращались в кашу — всегда храни время в UTC, используй ISO-формат, явно указывай таймзону при планировании задач, и не стесняйся использовать современные библиотеки. Не забывай синхронизировать время на сервере и проверять таймзону после каждого деплоя.
Для серверных задач и автоматизации рекомендую использовать date-fns или luxon, а для экспериментов — смотреть в сторону Temporal API. Не забывай про синхронизацию времени на сервере (ntpdate
, chrony
), и всегда проверяй, в какой таймзоне работает твой скрипт.
Если нужен VPS для экспериментов с Node.js и автоматизацией — заказать VPS. Для серьёзных задач и продакшена — выделенный сервер. Удачи в борьбе с датой и временем, и пусть твои скрипты всегда запускаются вовремя!
В этой статье собрана информация и материалы из различных интернет-источников. Мы признаем и ценим работу всех оригинальных авторов, издателей и веб-сайтов. Несмотря на то, что были приложены все усилия для надлежащего указания исходного материала, любая непреднамеренная оплошность или упущение не являются нарушением авторских прав. Все упомянутые товарные знаки, логотипы и изображения являются собственностью соответствующих владельцев. Если вы считаете, что какой-либо контент, использованный в этой статье, нарушает ваши авторские права, немедленно свяжитесь с нами для рассмотрения и принятия оперативных мер.
Данная статья предназначена исключительно для ознакомительных и образовательных целей и не ущемляет права правообладателей. Если какой-либо материал, защищенный авторским правом, был использован без должного упоминания или с нарушением законов об авторском праве, это непреднамеренно, и мы исправим это незамедлительно после уведомления. Обратите внимание, что переиздание, распространение или воспроизведение части или всего содержимого в любой форме запрещено без письменного разрешения автора и владельца веб-сайта. Для получения разрешений или дополнительных запросов, пожалуйста, свяжитесь с нами.