js计算n个月后的日期,并匹配月底,处理闰年,闰月
工作中遇到日期计算的需求,需要根据给定的日期计算出n个月后的日期,开始感觉挺简单一需求,因为现成的moment.js就有日期加月份计算的功能,但需求远不止简单的给定日期加月份,还要处理给定日期如是月底,需要n月后的日期同样是月底最后一天,如给定2022-01-31,计算1个月后的日期需要是2022-02-30,又例如给定2022-02-28,同样需要计算出1个月后结果应为2022-03-31.
export function addMonth(date, num) {
if (!date || !num) return;
var num1 = parseInt(num);
var d = new Date(date);
var thisMonth = d.getMonth() + 1;
var thisYear = d.getFullYear();
var thisDay = d.getDate();
var dateStr = "";
var addCount = thisMonth + num1;
var diffMonthCount = parseInt(addCount / 12); //取整
if ((thisMonth + num1) === 12 * diffMonthCount) { //如果是本年
if ((thisMonth + num1) === 12) {
diffMonthCount = 0;
} else {
diffMonthCount = diffMonthCount - 1;
}
}
if (thisMonth + num1 > 12) { //如果是大于一年
thisYear += diffMonthCount;
}
thisMonth = (addCount) - 12 * diffMonthCount;
if (thisMonth < 10) {
thisMonth = "0" + thisMonth;
}
var thatDate = new Date(thisYear, thisMonth, 0); //当天数为0 js自动处理为上一月的最后一天
var thatDay = thatDate.getDate();//指定年月的当月最大天数
let m1 = date.substring(5, 7);
if (thisDay === 30 || thisDay === 31 || (m1 === "02" && thisDay >= 28)) {
thisDay = thatDay;
if (date) {
let m2 = date.substring(5, 10);
// 成立日为2月份,且期限为整年的判断闰年
if (m2 === "02-28" && num % 12 === 0) {
if (!(thisYear % (thisYear % 100 ? 4 : 400))) {
thisDay = "29";
}
}
}
dateStr = thisYear + "-" + thisMonth + "-" + thisDay;
} else {
dateStr = addMonth2(date, num);
}
return dateStr;
}
function addMonth2(date, num) {
var monthnum = 0;
if (typeof (num) === "string") { monthnum = parseInt(num); } else { monthnum = num; }
if (typeof (date) === "string") { date = new Date(date); }
var year = date.getFullYear();
var month = date.getMonth() + 1;
var day = date.getDate();
var sumMonths = month + monthnum;
var newyear = year + parseInt(sumMonths / 12);
var newmonth = sumMonths % 12;
var newday = day;
let newmonth2 = "";
if (newmonth < 1) {
if (newmonth === 0) newyear--;
newmonth2 = 0 - (sumMonths - 1) % 12;
}
var da = new Date(newyear, newmonth2, 0);
newmonth = newmonth === 0 ? "12" : newmonth;
var _day = da.getDate() < newday ? da.getDate() : newday;
_day = _day < 10 && String(_day).length === 1 ? "0" + _day : _day;
newmonth = newmonth < 10 && String(newmonth).length === 1 ? "0" + newmonth : newmonth;
return newyear + "-" + newmonth + "-" + _day;
}