Как вычесть дни из даты JavaScript
Узнайте, как вычитать дни из объектов Date в JavaScript с помощью метода setDate(). Полное руководство с примерами, крайними случаями и альтернативами.
Как вычесть дни из обычного объекта Date в JavaScript?
Есть ли простой способ взять обычный объект Date (например, сегодня) и отнять от него X дней? Например, как вычислить дату, которая находится 5 дней назад?
Чтобы вычесть дни из обычного объекта Date в JavaScript, можно использовать метод setDate() в сочетании с getDate(). Например, чтобы получить дату, предшествующую сегодняшнему дню на 5 дней, используйте date.setDate(date.getDate() - 5). Такой подход автоматически обрабатывает переходы между месяцами и годами, что делает его самым простым способом выполнения арифметики дат в чистом JavaScript.
Содержание
- Использование метода setDate()
- Альтернативные подходы
- Вспомогательные функции для повторного использования
- Обработка крайних случаев
- Современные решения JavaScript
Использование метода setDate()
Самый распространённый и простой способ вычесть дни из объекта Date в JavaScript – использовать метод setDate() в сочетании с getDate(). Этот метод автоматически обрабатывает переходы между месяцами и годами, что делает его надёжным для расчётов дат.
Базовый синтаксис
let date = new Date();
let daysToSubtract = 5;
// Вычитаем 5 дней из текущей даты
date.setDate(date.getDate() - daysToSubtract);
Согласно Stack Overflow, этот подход работает как с положительными, так и с отрицательными значениями дней для добавления и вычитания соответственно. Метод setDate() работает напрямую с экземпляром Date, а не создаёт и не возвращает копию.
Пример: получение даты 5 дней назад
const today = new Date();
const fiveDaysAgo = new Date();
fiveDaysAgo.setDate(today.getDate() - 5);
console.log('Today:', today.toLocaleDateString());
console.log('5 days ago:', fiveDaysAgo.toLocaleDateString());
Этот подход особенно эффективен, потому что:
- Он прост и интуитивно понятен
- Автоматически обрабатывает переходы между месяцами (например, переход от 1 января к 31 декабря)
- Работает через границы лет
- Не требует внешних библиотек
Альтернативные подходы
Хотя setDate() является самым распространённым методом, существуют альтернативные способы вычитания дней из объекта Date, каждый из которых имеет свои преимущества и области применения.
Использование метода setTime()
Метод setTime() позволяет установить дату и время, добавляя или вычитая миллисекунды от эпохи Unix (1 января 1970 г.). Это удобно, когда нужна более точная контроль над вычислениями дат.
let date = new Date();
let daysToSubtract = 5;
let millisecondsPerDay = 24 * 60 * 60 * 1000;
// Вычитаем 5 дней, преобразовав их в миллисекунды
date.setTime(date.getTime() - (daysToSubtract * millisecondsPerDay));
Как объясняет GeeksforGeeks, метод setTime() устанавливает дату и время, добавляя или вычитая заданное количество миллисекунд от полуночи 1 января 1970 г.
Использование getTime() с арифметикой дат
Можно также работать напрямую с временными метками:
let date = new Date();
let daysToSubtract = 5;
let millisecondsPerDay = 24 * 60 * 60 * 1000;
// Создаём новый объект Date с скорректированной временной меткой
let newDate = new Date(date.getTime() - (daysToSubtract * millisecondsPerDay));
Этот подход неизменяемый – создаёт новый объект Date, а не изменяет исходный, что может быть полезно в функциональных контекстах.
Вспомогательные функции для повторного использования
Для более сложных приложений удобно создать переиспользуемые вспомогательные функции, которые могут вычитать любое количество дней из заданной даты.
Базовая вспомогательная функция
function subtractDays(date, days) {
const result = new Date(date);
result.setDate(result.getDate() - days);
return result;
}
// Использование
const today = new Date();
const fiveDaysAgo = subtractDays(today, 5);
Расширенная вспомогательная функция с проверкой
function subtractDays(date, days) {
if (!(date instanceof Date) || isNaN(date)) {
throw new Error('Invalid date provided');
}
if (typeof days !== 'number' || isNaN(days)) {
throw new Error('Days must be a valid number');
}
const result = new Date(date);
result.setDate(result.getDate() - days);
return result;
}
Согласно The Expert Developer, создание функции subtractDays() с аргументами объекта Date и количества дней делает функциональность переиспользуемой и более поддерживаемой.
Обработка крайних случаев
При работе с арифметикой дат важно понимать, как JavaScript обрабатывает крайние случаи и потенциальные проблемы.
Переходы между месяцами и годами
Объект Date в JavaScript автоматически обрабатывает переходы между месяцами и годами. Например:
const novemberFirst = new Date(2023, 10, 1); // 1 ноября 2023 г.
novemberFirst.setDate(novemberFirst.getDate() - 5);
console.log(novemberFirst.toLocaleDateString()); // 27 октября 2023 г.
Как объясняет DEV Community, если результат выходит за пределы допустимого диапазона для соответствующего месяца, setDate() обновит объект Date соответственно.
Учет часовых поясов
Объекты Date в JavaScript работают с UTC, но методы отображения обычно используют локальное время. При вычитании дней будьте внимательны к разнице часовых поясов:
const date = new Date('2023-01-01T00:00:00Z'); // Полночь UTC
date.setDate(date.getDate() - 1);
console.log(date.toISOString()); // Корректно обрабатывает преобразование часового пояса
Согласно Stack Overflow, getTime() работает с универсальным временем, поэтому корректно вычитает дни из объекта Date. При преобразовании в строку в указанном часовом поясе будет правильно отображён час для этого региона.
Учет перехода на летнее/зимнее время (DST)
При вычитании дней, которые могут пересекать границы DST, объект Date в JavaScript обрабатывает это автоматически:
// В период перехода на летнее время
const springDate = new Date('2023-03-12T03:00:00-05:00'); // До начала DST
springDate.setDate(springDate.getDate() - 1);
console.log(springDate.toString()); // Автоматически корректируется для DST
Современные решения JavaScript
Для современного JavaScript существует несколько подходов, которые обеспечивают более чистый синтаксис и лучшую обработку операций с датами.
Использование API Temporal (Stage 3 Proposal)
API Temporal – будущее работы с датами в JavaScript. Метод Temporal.PlainDate.subtract() предоставляет чистый, неизменяемый подход:
// Примечание: требуется полифилл Temporal или поддержка в будущих браузерах
const today = Temporal.now.plainDateISO();
const fiveDaysAgo = today.subtract({ days: 5 });
Согласно MDN, метод subtract() возвращает новый объект Temporal.PlainDate, представляющий дату, смещённую назад на заданную длительность.
Использование библиотеки Day.js
Для лёгкого решения с библиотекой, Day.js предоставляет простой API:
import dayjs from 'dayjs';
const today = dayjs();
const fiveDaysAgo = today.subtract(5, 'day');
console.log(fiveDaysAgo.format('YYYY-MM-DD'));
Метод subtract() Day.js возвращает клонированный объект Day.js с указанным количеством времени, вычтенным, что делает его цепляемым и неизменяемым.
Использование нативного Date с неизменяемыми операциями
Если вы предпочитаете оставаться без внешних библиотек и сохранять неизменяемость:
function subtractDaysImmutable(date, days) {
const dateCopy = new Date(date);
dateCopy.setDate(dateCopy.getDate() - days);
return dateCopy;
}
// Использование
const today = new Date();
const fiveDaysAgo = subtractDaysImmutable(today, 5);
Этот подход сохраняет исходный объект Date, создавая новый с скорректированной датой.
Заключение
Вычитание дней из объекта Date в JavaScript простое и надёжное, если использовать встроенный метод setDate(). Ключевые выводы:
- Используйте
setDate(date.getDate() - days)для самого надёжного и простого подхода, автоматически обрабатывающего переходы между месяцами и годами. - Учитывайте часовые пояса, особенно если выводите результаты пользователям из разных регионов.
- Создавайте вспомогательные функции для переиспользуемой арифметики дат в ваших приложениях.
- Будьте внимательны к крайним случаям (переходы DST, границы месяцев), хотя JavaScript обрабатывает их автоматически.
- Рассмотрите современные альтернативы как Temporal API или лёгкие библиотеки, такие как Day.js, для более сложных операций с датами.
Для большинства задач нативный метод setDate() обеспечивает идеальный баланс простоты и надёжности. При необходимости более продвинутой обработки дат рассмотрите использование проверенных библиотек или будущего API Temporal для лучшей поддерживаемости и меньшего количества ошибок.