← Назад к вопросам

Как работать с датами в JavaScript?

2.3 Middle🔥 171 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Как работать с датами в JavaScript

Работа с датами - одна из самых сложных задач в JavaScript. Встроенный Date объект имеет множество подводных камней. Расскажу о правильном подходе.

1. Встроенный Date объект (Осторожно!)

// Создание даты
const now = new Date();           // Текущая дата и время
const specific = new Date('2024-01-15'); // Строка ISO
const timestamp = new Date(1705276800000); // Миллисекунды с 1970

// Получение значений
const year = now.getFullYear();   // 2024
const month = now.getMonth();     // 0-11 (Январь = 0!) - ОПАСНО!
const day = now.getDate();        // 1-31
const hours = now.getHours();     // 0-23

// Потенциальная ошибка
const date = new Date('2024-02-15'); // Создаётся в локальной зоне или UTC?
console.log(date.toISOString());  // Зависит от браузера и ОС!

Проблемы:

  • getMonth() возвращает 0-11, что путает новичков
  • new Date('2024-01-15') может интерпретироваться как UTC или как локальная зона
  • Нет встроенной поддержки временных зон
  • Нет валидации - new Date('invalid') создаёт Invalid Date

2. Правильный способ - Date.parse и UTC методы

// Всегда используй ISO строки
const date = new Date('2024-01-15T10:30:00Z'); // Явно UTC

// Используй UTC методы для предсказуемости
const year = date.getUTCFullYear();    // 2024
const month = date.getUTCMonth();      // 0 (все ещё 0-11!)
const day = date.getUTCDate();         // 15

// Преобразование в миллисекунды
const timestamp = date.getTime(); // Миллисекунды
const seconds = Math.floor(date.getTime() / 1000);

// Форматирование
const iso = date.toISOString();          // '2024-01-15T10:30:00.000Z'
const locale = date.toLocaleDateString(); // '15.01.2024' (зависит от локали)

3. Day.js - Лёгкая альтернатива

Если не нужна полная мощь Moment.js, используй Day.js (всего 2KB):

import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import timezone from 'dayjs/plugin/timezone';

dayjs.extend(utc);
dayjs.extend(timezone);

// Создание
const date = dayjs('2024-01-15');
const now = dayjs();

// Операции с датами
const tomorrow = date.add(1, 'day');      // Завтра
const nextMonth = date.add(1, 'month');  // Следующий месяц
const daysAgo = date.diff(now, 'day');   // Разница в днях

// Форматирование
const formatted = date.format('DD.MM.YYYY'); // '15.01.2024'
const iso = date.toISOString();              // '2024-01-15T00:00:00.000Z'

// Временные зоны
const moscow = date.tz('Europe/Moscow');
const ny = date.tz('America/New_York');
const hours = moscow.format('HH:mm'); // '03:00' (если UTC была 00:00)

4. Moment.js - Полная функциональность (но тяжелый)

import moment from 'moment-timezone';

// Создание
const date = moment('2024-01-15', 'YYYY-MM-DD');

// Вычисления
const nextWeek = date.clone().add(7, 'days');
const daysUntilNewYear = moment('2025-01-01').diff(date, 'days');

// Форматирование с локализацией
moment.locale('ru');
const formatted = date.format('DD MMMM YYYY'); // '15 января 2024'

// Временные зоны
const moscow = date.clone().tz('Europe/Moscow');

Минус: Moment.js весит ~70KB (даже после минификации), так что лучше использовать Day.js.

5. Native JavaScript (Новое API)

Это относительно новое API, но поддержка улучшается:

// Получение компонентов даты без встроенного Date
const formatter = new Intl.DateTimeFormat('en-US', {
  year: 'numeric',
  month: '2-digit',
  day: '2-digit',
  hour: '2-digit',
  minute: '2-digit'
});

const parts = formatter.formatToParts(new Date());
// [{type: 'month', value: '01'}, {type: 'day', value: '15'}, ...]

const formatted = formatter.format(new Date()); // '01/15/2024, 10:30 AM'

6. Правильная работа с временными зонами

// ОШИБКА: Предполагаемая зона
const date = new Date('2024-01-15 10:00:00'); // Какая зона? Неясно!

// ПРАВИЛЬНО: Явная зона
const date = new Date('2024-01-15T10:00:00Z'); // Явно UTC
const moscow = dayjs(date).tz('Europe/Moscow'); // Преобразовать в Москву

// Получить текущее время в другой зоне
const now = dayjs().tz('Asia/Tokyo');
const hours = now.format('HH:mm');

7. Сравнение дат

const date1 = new Date('2024-01-15');
const date2 = new Date('2024-01-20');

// Сравнение
date1 < date2;  // true
date1.getTime() === date2.getTime(); // false

// С Day.js более читаемо
const d1 = dayjs('2024-01-15');
const d2 = dayjs('2024-01-20');

d1.isBefore(d2);  // true
d1.isSame(d2);    // false
d1.diff(d2, 'day'); // -5

8. Парсинг и валидация

// Встроенный Date - плохая валидация
const invalid = new Date('invalid-date');
console.log(invalid); // Invalid Date (не выбросит ошибку!)
console.log(invalid.getTime()); // NaN

// Правильная проверка
if (isNaN(invalid.getTime())) {
  console.log('Дата невалидна');
}

// С Day.js
const parsed = dayjs('2024-01-15');
if (!parsed.isValid()) {
  console.log('Дата невалидна');
}

9. Лучшие практики

// 1. Всегда используй UTC или явную зону
const date = dayjs.utc('2024-01-15T10:30:00Z');

// 2. Не смешивай встроенный Date с библиотеками
const date1 = new Date(); // Встроенный
const date2 = dayjs(date1); // Обёрнут в Day.js

// 3. Сохраняй даты в ISO формате в базе данных
const isoString = dayjs().toISOString(); // '2024-01-15T10:30:00.000Z'

// 4. Форматируй даты на клиенте (близко к пользователю)
const userDate = dayjs().tz(userTimezone).format('DD.MM.YYYY HH:mm');

// 5. Избегай парсинга строк - используй ISO или timestamp
const correct = dayjs('2024-01-15T10:30:00Z');
const wrong = dayjs('15/01/2024'); // Может неправильно парситься

10. Сравнение библиотек

БиблиотекаРазмерФункцииЗоны времениРекомендация
Date (встроенный)0KBБазовыеНетТолько простые случаи
Day.js2KBХорошиеПлагиныИспользуй это
Moment.js70KBВсеДаСлишком тяжелый
date-fns13KBМодульнаяНетФункциональный подход

Итог

Для большинства проектов используй Day.js - это правильный баланс между простотой и функциональностью. Избегай встроенного Date для чего-то серьёзного. Всегда явно указывай временные зоны и используй ISO формат для хранения.

Как работать с датами в JavaScript? | PrepBro