Комментарии (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.js | 2KB | Хорошие | Плагины | Используй это |
| Moment.js | 70KB | Все | Да | Слишком тяжелый |
| date-fns | 13KB | Модульная | Нет | Функциональный подход |
Итог
Для большинства проектов используй Day.js - это правильный баланс между простотой и функциональностью. Избегай встроенного Date для чего-то серьёзного. Всегда явно указывай временные зоны и используй ISO формат для хранения.