Работа с датами и временем в JavaScript: продвинутые методы и библиотеки

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение: почему стандартного Date() недостаточно?

Встроенный объект Date в JavaScript — это мощный, но не всегда удобный инструмент. При разработке сложных приложений на Node.js (например, планировщиков задач, систем аналитики или финансовых сервисов) разработчики сталкиваются с рядом проблем:

  • Мутабельность: методы setMonth() изменяют исходный объект.
  • Ограниченная поддержка часовых поясов: Date работает только с локальным временем и UTC.
  • Сложность форматирования: нет встроенного аналога strftime.
  • Парсинг строк: new Date("2023-13-01") не выбросит ошибку, а создаст "2024-01-01".

В этой статье мы рассмотрим продвинутые подходы к работе с датами и временем в Node.js, которые помогут избежать этих проблем и писать более надежный код.

1. Intl.DateTimeFormat: форматирование без внешних зависимостей

Современный JavaScript (ES6+) предоставляет встроенный API интернационализации Intl.DateTimeFormat. Это мощный инструмент, который позволяет форматировать даты и время под любую локаль без подключения сторонних библиотек.

Базовое использование

const date = new Date('2024-03-15T14:30:00Z');

// Форматирование для русской локали
const formatterRU = new Intl.DateTimeFormat('ru-RU', {
    year: 'numeric',
    month: 'long',
    day: 'numeric',
    weekday: 'long',
    hour: '2-digit',
    minute: '2-digit'
});

console.log(formatterRU.format(date));
// "пятница, 15 марта 2024 г., 17:30"

Продвинутые опции: часовые пояса и относительное время

// Форматирование с учетом часового пояса
const formatterTZ = new Intl.DateTimeFormat('en-US', {
    timeZone: 'America/New_York',
    dateStyle: 'full',
    timeStyle: 'short'
});
console.log(formatterTZ.format(date));
// "Friday, March 15, 2024 at 10:30 AM"

// Относительное форматирование (Intl.RelativeTimeFormat)
const rtf = new Intl.RelativeTimeFormat('ru', { numeric: 'auto' });
console.log(rtf.format(-5, 'day')); // "5 дней назад"
console.log(rtf.format(2, 'month')); // "через 2 месяца"

Этот подход идеален, когда нужно избежать лишних зависимостей, но требуется гибкое форматирование для пользовательского интерфейса.

2. Библиотека date-fns: модульность и функциональность

date-fns — это современная библиотека, построенная на принципах функционального программирования. Её главное преимущество — модульность: вы импортируете только те функции, которые нужны, что значительно уменьшает размер бандла.

Установка и базовые примеры

// Установка: npm install date-fns
import { format, addDays, subMonths, differenceInDays, isWeekend } from 'date-fns';
import { ru } from 'date-fns/locale';

const today = new Date();

// Форматирование с локалью
console.log(format(today, 'dd MMMM yyyy, EEEE', { locale: ru }));
// "15 марта 2024, пятница"

// Арифметика дат
const nextWeek = addDays(today, 7);
const lastMonth = subMonths(today, 1);

// Разница между датами
const diff = differenceInDays(nextWeek, today);
console.log(diff); // 7

// Проверка выходного дня
console.log(isWeekend(today)); // true или false

Сложные сценарии: сравнение и валидация

import { parse, isValid, isBefore, isAfter, startOfMonth, endOfMonth } from 'date-fns';

// Безопасный парсинг
const parsed = parse('2024-13-01', 'yyyy-MM-dd', new Date());
console.log(isValid(parsed)); // false — невалидная дата

// Работа с диапазонами
const start = startOfMonth(new Date(2024, 2, 1)); // 1 марта
const end = endOfMonth(new Date(2024, 2, 1));     // 31 марта

const targetDate = new Date(2024, 2, 15);
if (isAfter(targetDate, start) && isBefore(targetDate, end)) {
    console.log('Дата находится в марте 2024');
}

date-fns отлично подходит для проектов, где важна производительность и минимальный размер зависимостей.

3. Luxon: объектно-ориентированный подход с поддержкой часовых поясов

Luxon — это наследник популярной библиотеки Moment.js, но с современным API и полной поддержкой часовых поясов через IANA-идентификаторы. Она предоставляет неизменяемые объекты DateTime.

Установка и создание объектов

// Установка: npm install luxon
import { DateTime } from 'luxon';

// Текущее время в UTC
const nowUTC = DateTime.utc();
console.log(nowUTC.toString()); // "2024-03-15T14:30:00.000Z"

// Время в конкретном часовом поясе
const inMoscow = DateTime.now().setZone('Europe/Moscow');
console.log(inMoscow.toISO()); // "2024-03-15T17:30:00.000+03:00"

// Создание из ISO-строки
const fromISO = DateTime.fromISO('2024-03-15T14:30:00', { zone: 'America/New_York' });

Арифметика, форматирование и преобразование

const dt = DateTime.fromObject({ year: 2024, month: 3, day: 15, hour: 14 }, { zone: 'Asia/Tokyo' });

// Арифметика (неизменяемые операции)
const future = dt.plus({ days: 10, hours: 5 });
console.log(future.toFormat('dd.MM.yyyy HH:mm')); // "25.03.2024 19:00"

// Разница между датами
const diff = future.diff(dt, ['days', 'hours']).toObject();
console.log(diff); // { days: 10, hours: 5 }

// Переход в другой часовой пояс
const inLondon = dt.setZone('Europe/London');
console.log(inLondon.toFormat('HH:mm')); // "05:00" (разница -9 часов)

Работа с интервалами

import { Interval } from 'luxon';

const start = DateTime.fromISO('2024-03-01');
const end = DateTime.fromISO('2024-03-31');
const interval = Interval.fromDateTimes(start, end);

// Проверка вхождения
const checkDate = DateTime.fromISO('2024-03-15');
console.log(interval.contains                

Блоги

Рекомендаций по книгам