Вычисление разницы между двумя датами в месяцах на JS
Пройдите тест, узнайте какой профессии подходите
Быстрый ответ
Ниже представлен код функции, рассчитывающей разницу в месяцах между двумя датами в JavaScript:
const monthDiff = (d1, d2) => (d2.getFullYear() – d1.getFullYear()) * 12 + d2.getMonth() – d1.getMonth();
// Пример вызова функции
console.log(monthDiff(new Date('2023-01-01'), new Date('2023-04-01'))); // 3
Эта функция вычисляет общее количество месяцев между двумя датами, умножая разницу в годах на 12 и добавляя к этому разницу в месяцах.
Учет сложностей — не все так просто, как кажется
Простая логика вычисления может оказаться недостаточной, если учесть частичность месяцев, возможность отрицательной разницы, а также разнообразность продолжительности месяцев.
Округление долей месяца
Возникают неопределенности, если даты приходятся на середину месяца. В таких случаях требуется определить стратегию округления долей месяцев.
Отрицательная разница
Если начальная дата оказывается позже конечной, функция вернет отрицательное значение, так как это всё равно что "путешествовать" назад во времени.
Учет продолжительности месяцев
Месяцы не одинаковы по числу дней, и это может повлиять на точность расчетов, особенно важных, к примеру, для февраля.
Чтобы это учесть, можно дополнить функцию:
const monthDiff = (d1, d2, roundUpFractionalMonths = false) => {
let months = (d2.getFullYear() – d1.getFullYear()) * 12 + d2.getMonth() – d1.getMonth();
const partialMonth = (d2.getDate() < d1.getDate());
if (roundUpFractionalMonths && partialMonth) {
months++;
}
return months;
};
// Пример с округлением долей месяца
console.log(monthDiff(new Date('2023-01-15'), new Date('2023-04-14'), true)); // 3
Параметр roundUpFractionalMonths
позволяет округлять результат в большую сторону, если есть доли месяца.
Включать ли конечный месяц: вопрос выбора
Вполне возможно, что потребуется скорректировать расчет так, чтобы либо включать, либо исключать конечный месяц.
Исключение конечного месяца
По умолчанию конечный месяц не учитывается в результате, если его день раньше дня начальной даты.
Включение конечного месяца
Если желательно учесть конечный месяц полностью, можно немного изменить функцию или просто прибавить 1 к полученному результату.
Визуализация
Чтобы понять механику расчета разницы между датами, можно воспользоваться аналогией с лифтом, где каждый этаж соответствует одному месяцу.
🏢 Начальная дата: 3 этаж (март) 🏢 Конечная дата: 8 этаж (август)
🛗 Путь лифта: [3] ⬆️⬆️⬆️⬆️⬆️ [8]
Продвинутые методы для опытных разработчиков
Для решения более сложных задач пригодятся следующие подходы:
Удобные в работе библиотеки
Можно облегчить свою задачу, используя библиотеки вроде date-fns
или Day.js
, которые уже содержат необходимые функции.
Тестирование бизнес-логики
Хорошим тоном будет накатить некоторые "юнит-тесты", учитывающие влияние високосных годов, секунд и разницу в часовых поясах.
Стандартизация дат
Чтобы избежать проблем с форматами дат, рекомендуется использовать строки в формате ISO 8601 (YYYY-MM-DD
).
Полезные материалы
- Дата – JavaScript | MDN – официальная документация по объекту Date.
- В чем разница между двуми датами в JavaScript? – Stack Overflow – обсуждение расчета разницы между датами.
- date-fns – манипуляции с датами в JavaScript – метод
differenceInMonths
из библиотекиdate-fns
. - GitHub – you-dont-need/You-Dont-Need-Momentjs – альтернативы Moment.js для работы с датами.
- Все о датах в JavaScript | CSS-Tricks – руководство по работе с датами в JavaScript.
- ISO – Формат даты и времени ISO 8601 – стандартный формат представления дат и времени.