Дата и время в JavaScript: объект Date без боли
Содержание
О проверке кода. Примеры не запускались — в отличие от материалов по Node.js с фактическим выводом. Говорим прямо, а не ставим бейдж «проверено».
Объект Date — самая критикуемая часть JavaScript: нумерация месяцев с нуля, путаница таймзон, неудобный API. Но базовые задачи он решает, если знать ловушки.
Создание даты
new Date(); // текущий момент
new Date('2026-07-17'); // из ISO-строки (рекомендуется)
new Date('2026-07-17T14:30:00'); // с временем
new Date(2026, 6, 17); // ⚠️ год, месяц (6 = ИЮЛЬ!), день
new Date(1752761400000); // из timestamp (миллисекунды)
Date.now(); // timestamp текущего момента — просто число
Самый надёжный способ — ISO-строка '2026-07-17'. Конструктор с числами new Date(2026, 6, 17) опасен из-за месяцев с нуля (об этом ниже). Парсинг произвольных строк вроде '17.07.2026' ненадёжен и зависит от браузера — не используйте.
Главная ловушка: месяцы с нуля
const d = new Date(2026, 6, 17); // это 17 ИЮЛЯ, а не июня!
d.getMonth(); // 6 — июль, потому что январь = 0
d.getDate(); // 17 — а вот дни считаются с 1
new Date(2026, 0, 1); // 1 января
new Date(2026, 11, 31); // 31 декабря
Месяцы в Date нумеруются с нуля: январь — 0, декабрь — 11. А дни месяца — с 1. Эта непоследовательность порождает ошибки на единицу в каждом проекте. Правило: увидели число месяца в конструкторе или getMonth — вычтите или прибавьте единицу в уме. Ещё одна причина предпочесть ISO-строки, где месяц пишется по-человечески.
Получение частей даты
const d = new Date('2026-07-17T14:30:45');
d.getFullYear(); // 2026 (getYear устарел — не используйте)
d.getMonth(); // 6 (июль, с нуля!)
d.getDate(); // 17 (день месяца)
d.getDay(); // 5 (день недели: 0 = воскресенье)
d.getHours(); // 14
d.getMinutes(); // 30
d.getTime(); // timestamp в миллисекундах
Осторожно с двумя похожими: getDate() — число месяца (17), getDay() — день недели (0–6, где 0 = воскресенье). Их постоянно путают. И всегда getFullYear(), а не устаревший getYear().
Форматирование: toLocale вместо ручной сборки
const d = new Date('2026-07-17T14:30:00');
// ❌ хрупкая ручная сборка (и месяц с нуля не забыть)
`${d.getDate()}.${d.getMonth() + 1}.${d.getFullYear()}`; // '17.7.2026'
// ✅ локализованное форматирование
d.toLocaleDateString('ru-RU'); // '17.07.2026'
d.toLocaleString('ru-RU'); // '17.07.2026, 14:30:00'
d.toLocaleDateString('ru-RU', { day: 'numeric', month: 'long', year: 'numeric' });
// '17 июля 2026 г.'
d.toISOString(); // '2026-07-17T14:30:00.000Z' — для API и хранения
toLocaleDateString/toLocaleString с локалью — правильный способ показать дату пользователю. Они сами расставят разделители, порядок и падежи по локали. Ручная сборка из getDate/getMonth хрупка и спотыкается о месяцы с нуля. Для хранения и обмена — toISOString() (стандартный машинный формат).
Разница между датами
const start = new Date('2026-07-01');
const end = new Date('2026-07-17');
const diffMs = end - start; // 1382400000 (миллисекунды)
const diffDays = diffMs / (1000 * 60 * 60 * 24); // 16 дней
Вычитание дат даёт разницу в миллисекундах — при арифметике Date автоматически приводится к числу (timestamp). Дальше делят на нужную единицу: /1000 → секунды, /(1000*60) → минуты, /(1000*60*60*24) → дни. Для «прибавить 3 дня» удобнее setDate(d.getDate() + 3), который сам обрабатывает переход через границу месяца.
Timestamp — дата как число
Date.now(); // 1752761400000 — текущий момент числом
const d = new Date('2026-07-17');
d.getTime(); // timestamp этой даты
// сравнение дат — как чисел
date1.getTime() < date2.getTime(); // раньше ли date1
Timestamp — миллисекунды с 1 января 1970 (эпоха Unix). Хранить и сравнивать даты как числа удобнее, чем как объекты: сравнение, сортировка, вычисление разницы — обычная арифметика. Многие API отдают даты именно в этом формате.
Когда брать библиотеку
Встроенного Date хватает для простых задач. Но как только появляются таймзоны, разбор нестандартных форматов, сложная арифметика — берут инструмент посильнее:
date-fns— набор функций (format,addDays,differenceInDays), модульный и лёгкий;Temporal— новый стандарт языка, который чинит исторические проблемыDate(иммутабельность, честные таймзоны, месяцы с единицы). Постепенно появляется в средах.
Правило то же, что и везде на сайте: инструмент под задачу. Для «показать дату» — встроенный Date, для календарного приложения — библиотека.
Смежные темы: числа и Math — timestamp это число; строки — форматирование; типы данных. Полный список — в уроках JavaScript.