Работа с датами и временем в JavaScript (Node.js): от основ до продвинутых техник
Работа с датами и временем — одна из самых частых задач в backend-разработке. Будь то логирование событий, расчёт сроков, генерация отчётов или работа с API, умение корректно обрабатывать временные метки — критически важный навык. В этой статье мы разберём все ключевые аспекты работы с датами в среде Node.js: от встроенного объекта Date до популярных библиотек, которые упрощают жизнь разработчика.
1. Встроенный объект Date: основы и подводные камни
В JavaScript за работу с датами отвечает встроенный объект Date. Он предоставляет базовые методы для создания, чтения и манипуляции датами. Однако у него есть ряд особенностей, которые важно знать.
Создание объекта Date
Самый простой способ получить текущую дату и время:
const now = new Date();
console.log(now); // 2025-03-20T14:30:00.000Z (пример)
Можно создать дату из строки, timestamp (миллисекунды с 1 января 1970 года) или задав компоненты вручную:
// Из строки (ISO 8601)
const dateFromString = new Date("2025-12-25T10:00:00Z");
// Из timestamp
const dateFromTimestamp = new Date(1735048800000);
// Из компонентов (год, месяц (0-11), день, час, минута, секунда, миллисекунда)
const dateFromParts = new Date(2025, 11, 25, 10, 0, 0, 0); // 25 декабря 2025 10:00:00
console.log(dateFromParts); // 2025-12-25T07:00:00.000Z (зависит от часового пояса)
Важно: Месяцы в JavaScript нумеруются с 0 (январь — 0, декабрь — 11). Это частая причина ошибок.
Получение компонентов даты
Объект Date предоставляет методы для получения отдельных компонентов:
const date = new Date();
console.log(date.getFullYear()); // 2025
console.log(date.getMonth()); // 2 (март, так как отсчёт с 0)
console.log(date.getDate()); // 20
console.log(date.getDay()); // 4 (четверг, 0 - воскресенье)
console.log(date.getHours()); // 17
console.log(date.getMinutes()); // 45
console.log(date.getSeconds()); // 12
console.log(date.getMilliseconds());// 345
console.log(date.getTime()); // 1742474712345 (timestamp)
Обратите внимание: все эти методы возвращают значения в локальном часовом поясе сервера. Для работы с UTC используйте методы с приставкой getUTC... (например, getUTCFullYear()).
Манипуляции с датами
Изменение даты производится через set-методы. Они мутируют исходный объект:
const date = new Date();
date.setFullYear(2026);
date.setMonth(0); // январь
date.setDate(15);
console.log(date); // 2026-01-15T... (остальные компоненты сохраняются)
Подводный камень: set-методы автоматически корректируют дату. Например, если задать 32 января, дата станет 1 февраля. Это может быть как удобно, так и неожиданно.
2. Форматирование дат и вывод в нужном виде
Встроенный метод toLocaleDateString() позволяет вывести дату в формате, принятом в определённой локали:
const date = new Date(2025, 11, 25);
console.log(date.toLocaleDateString('ru-RU')); // 25.12.2025
console.log(date.toLocaleDateString('en-US')); // 12/25/2025
console.log(date.toLocaleDateString('de-DE')); // 25.12.2025
Для более гибкого форматирования можно использовать Intl.DateTimeFormat:
const formatter = new Intl.DateTimeFormat('ru-RU', {
year: 'numeric',
month: 'long',
day: 'numeric',
weekday: 'long',
hour: '2-digit',
minute: '2-digit'
});
console.log(formatter.format(new Date())); // "четверг, 20 марта 2025 г., 17:45"
Однако для сложных форматов (например, "2025-03-20T14:30:00+03:00") или кастомных шаблонов лучше использовать библиотеки (о них ниже).
3. Библиотеки для работы с датами: moment.js, date-fns и day.js
Встроенный Date хорош для простых задач, но для серьёзной работы с датами (парсинг, манипуляции, временные зоны) лучше использовать специализированные библиотеки. Рассмотрим три популярных варианта.
moment.js (легенда, но уже legacy)
Долгое время была стандартом де-факто. Сейчас её использование не рекомендуется для новых проектов из-за большого размера и проблем с производительностью. Однако на старых проектах она всё ещё встречается.
const moment = require('moment');
const now = moment();
console.log(now.format('YYYY-MM-DD HH:mm:ss')); // 2025-03-20 17:45:12
console.log(now.add(7, 'days').format('dddd')); // "четверг" (через неделю)
// Парсинг строки
const parsed = moment('25.12.2025', 'DD.MM.YYYY');
console.log(parsed.toDate()); // 2025-12-25T00:00:00.000Z
date-fns (современный и лёгкий)
Библиотека, построенная на принципах функционального программирования. Каждая функция — отдельный модуль, что позволяет не тащить весь код в бандл.
const { format, addDays, parse, differenceInDays } = require('date-fns');
const { ru } = require('date-fns/locale');
const now = new Date();
console.log(format(now, 'dd.MM.yyyy HH:mm')); // 20.03.2025 17:45
console.log(format(now, 'PPPP', { locale: ru })); // "четверг, 20 марта 2025 г."
const future = addDays(now, 10);
console.log(differenceInDays(future, now)); // 10
// Парсинг
const parsed = parse('25.12.2025', 'dd.MM.yyyy', new Date());
console.log(parsed); // 2025-12-25T00:00:00.000Z
day.js (минималистичная альтернатива moment)
Очень