Даты: Intl и Temporal
Одна и та же дата в Москве и Нью-Йорке — разные «01:00» и «23:00». Хранить нужно время одинаково, показывать — каждому по-своему.
Храним в UTC, форматируем у пользователя
// сохраняем моментальное время как ISO 8601 с Z:
"2026-04-12T19:30:00.000Z" // UTC, точка отсчёта
// в БД (урок 56) — тот же ISO или timestamp with time zone
const start = new Date("2026-04-12T19:30:00.000Z");
Форматирование по локали
new Intl.DateTimeFormat("ru-RU", {
dateStyle: "long", timeStyle: "short",
timeZone: "UTC" // или "Europe/Moscow"
}).format(start);
// "12 апреля 2026 г., 19:30" — для en-US будет иначе
Temporal — новый API дат
// Intl + date-fns закрывают 95% задач. Temporal (следующая
// генерация API) уберёт боль Date: immutable, явные пояса:
// Temporal.Now.zonedDateTimeISO("Europe/Moscow")
💡
Не выдумывайте «свой» формат: ISO 8601 с таймзоной — контракт, понятный ещё миллиону библиотек. Для календарных «дата без времени» (день рождения) — тип date без пояса.
ℹ️
Частые баги: «спится в 01:00» (летнее время, DST), «вчера началось на сутки раньше» (прибавили 24 часа к 23:00). Момент времени ≠ календарная дата: выбирайте тип осознанно.