Существует два подхода: математический & amp; быстрые, но подверженные капризам в календаре, или итеративные и amp; медленный, но обрабатывает все странности (или, по крайней мере, делегаты обрабатывают их в хорошо протестированной библиотеке).
Если вы перебираете календарь, увеличивая начальную дату на один месяц & amp; если мы пройдем дату окончания. Это делегирует обработку аномалий встроенным классам Date (), но может быть медленным IF , что вы делаете это для большого количества дат. Ответ Джеймса использует такой подход. Насколько мне не нравится эта идея, я думаю, что это «самый безопасный» подход, и если вы делаете только один расчет, разница в производительности действительно незначительна. Мы склонны пытаться переопределить задачи, которые будут выполняться только один раз.
Теперь, если вы вычисляете эту функцию в наборе данных, вы, вероятно, не хотите запускать эту функцию в каждой строке ( или не дай бог, несколько раз за запись). В этом случае вы можете использовать почти любой из других ответов здесь , кроме принятого ответа, который просто неверен (разница между new Date()
и new Date()
равна -1)?
Вот мой удар по математическому и быстрому подходу, который учитывает разные месяцы и високосные годы. Вы действительно должны использовать только такую функцию, если вы будете применять ее к набору данных (выполняя этот расчет над & amp; over). Если вам просто нужно сделать это один раз, используйте итеративный подход Джеймса выше, поскольку вы делегируете обработку всех (многих) исключений для объекта Date ().
function diffInMonths(from, to){
var months = to.getMonth() - from.getMonth() + (12 * (to.getFullYear() - from.getFullYear()));
if(to.getDate() < from.getDate()){
var newFrom = new Date(to.getFullYear(),to.getMonth(),from.getDate());
if (to < newFrom && to.getMonth() == newFrom.getMonth() && to.getYear() %4 != 0){
months--;
}
}
return months;
}