我正在寻找最简单、最干净的方法将X个月添加到JavaScript日期中。

我宁愿不处理一年的滚动,也不愿意自己写函数。

有什么内置的东西可以做到这一点吗?


当前回答

一个简单的答案可以是:

function addMonthsToDate(date, numMonths){
    // Add months
    date.setMonth(date.getMonth() + numMonths);
    
    // Zero the time component
    date.setHours(0, 0, 0, 0);
    return date;
}

这可以被称为-增加两个月:

console.log(addMonthsToDate(new Date(),2));

其他回答

正如大多数答案突出显示的那样,我们可以使用setMonth()方法和getMonth()方法一起为给定的日期添加特定的月份数。

例子:(@ChadD在他的回答中提到。)

Var x = 12;//或任何偏移量 var CurrentDate = new Date(); CurrentDate.setMonth(CurrentDate.getMonth() + x);

但是我们应该小心地使用这个解决方案,因为我们会在边界情况下遇到麻烦。

要处理边缘情况,下面链接中给出的答案是有帮助的。 https://stackoverflow.com/a/13633692/3668866

来自@bmpsini和@Jazaret的回复,但没有扩展原型:使用普通函数(为什么扩展本机对象是一种糟糕的做法?)

function isLeapYear(year) { 
    return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0)); 
}

function getDaysInMonth(year, month) {
    return [31, (isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
}

function addMonths(date, value) {
    var d = new Date(date),
        n = date.getDate();
    d.setDate(1);
    d.setMonth(d.getMonth() + value);
    d.setDate(Math.min(n, getDaysInMonth(d.getFullYear(), d.getMonth())));
    return d;
}

使用它:

var nextMonth = addMonths(new Date(), 1);

这个函数处理边缘情况,并且速度很快:

function addMonthsUTC (date, count) {
  if (date && count) {
    var m, d = (date = new Date(+date)).getUTCDate()

    date.setUTCMonth(date.getUTCMonth() + count, 1)
    m = date.getUTCMonth()
    date.setUTCDate(d)
    if (date.getUTCMonth() !== m) date.setUTCDate(0)
  }
  return date
}

测试:

> d = new Date('2016-01-31T00:00:00Z');
Sat Jan 30 2016 18:00:00 GMT-0600 (CST)
> d = addMonthsUTC(d, 1);
Sun Feb 28 2016 18:00:00 GMT-0600 (CST)
> d = addMonthsUTC(d, 1);
Mon Mar 28 2016 18:00:00 GMT-0600 (CST)
> d.toISOString()
"2016-03-29T00:00:00.000Z"

非utc日期更新:(由A.Hatchkins编写)

function addMonths (date, count) {
  if (date && count) {
    var m, d = (date = new Date(+date)).getDate()

    date.setMonth(date.getMonth() + count, 1)
    m = date.getMonth()
    date.setDate(d)
    if (date.getMonth() !== m) date.setDate(0)
  }
  return date
}

测试:

> d = new Date(2016,0,31);
Sun Jan 31 2016 00:00:00 GMT-0600 (CST)
> d = addMonths(d, 1);
Mon Feb 29 2016 00:00:00 GMT-0600 (CST)
> d = addMonths(d, 1);
Tue Mar 29 2016 00:00:00 GMT-0600 (CST)
> d.toISOString()
"2016-03-29T06:00:00.000Z"

下面的函数在JavaScript中为日期添加月份(源代码)。它考虑了年的滚动和不同的月份长度:

function addMonths(date, months) { var d = date.getDate(); date.setMonth(date.getMonth() + +months); if (date.getDate() != d) { date.setDate(0); } return date; } // Add 12 months to 29 Feb 2016 -> 28 Feb 2017 console.log(addMonths(new Date(2016,1,29),12).toString()); // Subtract 1 month from 1 Jan 2017 -> 1 Dec 2016 console.log(addMonths(new Date(2017,0,1),-1).toString()); // Subtract 2 months from 31 Jan 2017 -> 30 Nov 2016 console.log(addMonths(new Date(2017,0,31),-2).toString()); // Add 2 months to 31 Dec 2016 -> 28 Feb 2017 console.log(addMonths(new Date(2016,11,31),2).toString());

上面的解决方案涵盖了从一个月移动的天数多于目标月份的边缘情况。如。

增加12个月至2020年2月29日(应该是2021年2月28日) 增加一个月至2020年8月31日(应该是2020年9月30日)

如果在应用setMonth时,月份的日期发生了变化,那么由于月份长度的差异,我们知道已经溢出到下一个月。在本例中,我们使用setDate(0)返回到上个月的最后一天。

注意:这个答案的这个版本取代了之前的版本(下面),之前的版本没有优雅地处理不同的月份长度。

var x = 12; //or whatever offset
var CurrentDate = new Date();
console.log("Current date:", CurrentDate);
CurrentDate.setMonth(CurrentDate.getMonth() + x);
console.log("Date after " + x + " months:", CurrentDate);

考虑到这些答案中没有一个会在月份变化时解释当年的情况,你可以在下面找到我做的一个答案,它应该可以处理这个问题:

方法:

Date.prototype.addMonths = function (m) {
    var d = new Date(this);
    var years = Math.floor(m / 12);
    var months = m - (years * 12);
    if (years) d.setFullYear(d.getFullYear() + years);
    if (months) d.setMonth(d.getMonth() + months);
    return d;
}

用法:

return new Date().addMonths(2);