Дата и время в JavaScript: от основ до сложных решений
Работа с датами и временем - частая задача в веб-разработке. JavaScript предоставляет встроенный объект Date, который позволяет создавать, читать и изменять даты. В этой статье мы рассмотрим основные методы, типичные ошибки и альтернативные подходы.
Основные принципы работы с датами в JavaScript
Основной способ создания объекта даты - конструктор new Date(). Без аргументов он возвращает текущую дату и время. Для получения компонентов даты используются методы getFullYear(), getMonth() (0-11), getDate(), getHours() и т.д. Пример:
const now = new Date();
console.log(now.getFullYear()); // текущий год
console.log(now.getMonth()); // месяц (0 - январь)
console.log(now.getDate()); // день месяцаJs date (дата в javascript)
Важно помнить, что месяц отсчитывается от 0, а день недели от 0 (воскресенье). Это часто приводит к ошибкам. Для установки компонентов существуют методы setFullYear, setMonth и т.д., но они изменяют исходный объект. Если нужно получить новую дату, лучше создать копию.
Типичная ошибка: путаница с месяцем. Например, new Date(2025, 1, 10) создаст 10 февраля, а не января. Также нельзя полагаться на автоматическое преобразование строк - парсинг может дать неожиданные результаты в разных браузерах.
Как создать дату из строки в произвольном формате?
Можно использовать конструктор new Date(dateString) или статический метод Date.parse(). Однако надёжнее всего разбирать строку вручную, особенно если формат не соответствует ISO (YYYY-MM-DD).
const isoDate = new Date('2025-03-15T12:00:00Z');
console.log(isoDate.toISOString());
// Ручной разбор строки DD.MM.YYYY
function parseDMY(str) {
const [day, month, year] = str.split('.');
return new Date(year, month - 1, day);
}
console.log(parseDMY('15.03.2025'));
Проблема: конструктор Date при передаче строки в нестандартном формате может интерпретировать её по-разному. Лучше всегда явно указывать части даты или использовать библиотеки (например, date-fns).
Как получить текущее время в миллисекундах?
Используется статический метод Date.now(), который возвращает количество миллисекунд с 1 января 1970 года UTC. Это удобно для измерения временных интервалов.
const start = Date.now();
// какой-то код
const end = Date.now();
console.log('Время выполнения:', end - start, 'мс');
Ошибка: использование new Date().getTime() даёт тот же результат, но создаёт лишний объект. Date.now() производительнее.
Как отформатировать дату в локальном формате, например, для России?
Метод toLocaleDateString() с указанием локали 'ru-RU' и опций позволяет гибко настроить вывод. Альтернатива - Intl.DateTimeFormat.
const date = new Date(2025, 2, 15); // 15 марта 2025
console.log(date.toLocaleDateString('ru-RU', {
year: 'numeric',
month: 'long',
day: 'numeric'
})); // "15 марта 2025 г."
Типичная ошибка: забыть указать локаль - тогда используется локаль браузера, что может дать неожиданный формат. Также не все опции поддерживаются в старых браузерах.
Как добавить определённое количество дней к дате?
Используется метод setDate() с вычислением нового дня. Важно: метод изменяет исходный объект. Для сохранения оригинала создаётся копия.
const today = new Date();
const nextWeek = new Date(today);
nextWeek.setDate(today.getDate() + 7);
console.log('Сегодня:', today.toDateString());
console.log('Через неделю:', nextWeek.toDateString());
Проблема: при добавлении большого количества дней могут возникнуть проблемы с переходом на другой месяц или год, но setDate() корректно обрабатывает переполнение. Однако нужно следить за мутабельностью - если не скопировать, исходная дата изменится.
Как безопасно скопировать объект Date?
Создание копии через new Date(original.getTime()) или new Date(+original). Это гарантирует, что изменения не затронут исходную дату.
const original = new Date(2025, 0, 1);
const copy = new Date(+original);
copy.setFullYear(2026);
console.log(original.getFullYear()); // 2025
console.log(copy.getFullYear()); // 2026
Ошибка: присваивание copy = original не создаёт копию, а только ссылку. Изменение copy изменит original.
Дополнительные примеры работы с датами
Здесь представлены более сложные сценарии, которые помогут углубить понимание работы с датами.
Пример 1: Вычисление разницы между датами в днях.
function daysBetween(date1, date2) {
const oneDay = 24 * 60 * 60 * 1000; // миллисекунд в одном дне
const diff = Math.abs(date1 - date2);
return Math.round(diff / oneDay);
}
const d1 = new Date('2025-01-01');
const d2 = new Date('2025-12-31');
console.log('Дней между:', daysBetween(d1, d2));
Дней между: 364
Пример 2: Получение массива последних 7 дней.
function last7Days() {
const result = [];
const today = new Date();
for (let i = 6; i >= 0; i--) {
const day = new Date(+today);
day.setDate(today.getDate() - i);
result.push(day.toDateString());
}
return result;
}
console.log(last7Days());
['Mon Mar 10 2025', 'Tue Mar 11 2025', 'Wed Mar 12 2025', 'Thu Mar 13 2025', 'Fri Mar 14 2025', 'Sat Mar 15 2025', 'Sun Mar 16 2025']
Пример 3: Проверка, является ли год високосным.
function isLeapYear(year) {
return (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0);
}
console.log(isLeapYear(2024)); // true
console.log(isLeapYear(2025)); // false
true false
Пример 4: Форматирование даты с помощью Intl.DateTimeFormat.
const formatter = new Intl.DateTimeFormat('ru-RU', {
weekday: 'long',
year: 'numeric',
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit'
});
console.log(formatter.format(new Date()));
воскресенье, 16 мар. 2025 г., 14:35
Пример 5: Парсинг даты из формата DD.MM.YYYY с валидацией.
function parseRussianDate(str) {
const parts = str.split('.');
if (parts.length !== 3) return null;
const [day, month, year] = parts.map(Number);
if (day < 1 || day > 31 || month < 1 || month > 12) return null;
const date = new Date(year, month - 1, day);
// проверяем, что дата коррективна (например, 31 февраля)
if (date.getDate() !== day || date.getMonth() !== month - 1) return null;
return date;
}
console.log(parseRussianDate('31.02.2025')); // null (некорректная дата)
console.log(parseRussianDate('15.03.2025')); // Дата объекта
null Sat Mar 15 2025 00:00:00 GMT+0300 (Москва, стандартное время)