用于将X月添加到日期的JavaScript函数

时间:2010-04-24 21:01:52

标签: javascript date

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

我不想handle the rolling over of the year或不得write my own function

内置的内容可以做到吗?

20 个答案:

答案 0 :(得分:243)

我认为应该这样做:

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);

我认为它应该自动处理递增到适当的年份并修改到适当的月份。

答案 1 :(得分:52)

我正在使用moment.jsdate-time manipulations。 添加一个月的示例代码:

try
{
    SqlDataAdapter1.Update(Dataset1.Tables["Table1"]);
}
catch (Exception e)
{
    // Error during Update, add code to locate error, reconcile  
    // and try to update again.
}

答案 2 :(得分:22)

此函数处理边缘情况并且速度很快:

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"

答案 3 :(得分:13)

考虑到这些答案都不会占当月变化的当年,你可以在下面找到我应该处理的答案:

方法:

Sub Foo()

    Dim cmd_Command As String = "DIR %USERPROFILE%/Desktop/*.* > %USERPROFILE%/Files.log"

    CreateObject("WScript.Shell").Exec("CMD /C " & cmd_Command)

End Sub

用法:

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;
}

答案 4 :(得分:7)

取自@bmpsini@Jazaret回复,但未扩展原型:使用普通函数(Why is extending native objects a bad practice?):

$ cap production invoke:rake TASK=some:rake_task

使用它:

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;
}

答案 5 :(得分:3)

简单解决方案:2678400000是31天(毫秒)

var oneMonthFromNow = new Date((+new Date) + 2678400000);

<强>更新

使用此数据构建我们自己的功能:

  • 2678400000 - 31天
  • 2592000000 - 30天
  • 2505600000 - 29天
  • 2419200000 - 28天

答案 6 :(得分:2)

d = new Date();

alert(d.getMonth()+1);

月份有一个从0开始的索引,它应该警告(4)这是5(可能);

答案 7 :(得分:2)

从上面的答案中,唯一一个处理边缘情况的人(来自datejs库的bmpasini)有一个问题:

var date = new Date("03/31/2015");
var newDate = date.addMonths(1);
console.log(newDate);
// VM223:4 Thu Apr 30 2015 00:00:00 GMT+0200 (CEST)

好的,但是:

newDate.toISOString()
//"2015-04-29T22:00:00.000Z"
更糟糕的是:

var date = new Date("01/01/2015");
var newDate = date.addMonths(3);
console.log(newDate);
//VM208:4 Wed Apr 01 2015 00:00:00 GMT+0200 (CEST)
newDate.toISOString()
//"2015-03-31T22:00:00.000Z"

这是由于没有设置时间,因此恢复到00:00:00,由于时区或节省时间的变化或任何其他原因,这可能会导致前一天故障......

这是我提出的解决方案,它没有这个问题,而且我认为它更优雅,因为它不依赖于硬编码值。

/**
* @param isoDate {string} in ISO 8601 format e.g. 2015-12-31
* @param numberMonths {number} e.g. 1, 2, 3...
* @returns {string} in ISO 8601 format e.g. 2015-12-31
*/
function addMonths (isoDate, numberMonths) {
    var dateObject = new Date(isoDate),
        day = dateObject.getDate(); // returns day of the month number

    // avoid date calculation errors
    dateObject.setHours(20);

    // add months and set date to last day of the correct month
    dateObject.setMonth(dateObject.getMonth() + numberMonths + 1, 0);

    // set day number to min of either the original one or last day of month
    dateObject.setDate(Math.min(day, dateObject.getDate()));

    return dateObject.toISOString().split('T')[0];
};

单位测试成功:

function assertEqual(a,b) {
    return a === b;
}
console.log(
    assertEqual(addMonths('2015-01-01', 1), '2015-02-01'),
    assertEqual(addMonths('2015-01-01', 2), '2015-03-01'),
    assertEqual(addMonths('2015-01-01', 3), '2015-04-01'),
    assertEqual(addMonths('2015-01-01', 4), '2015-05-01'),
    assertEqual(addMonths('2015-01-15', 1), '2015-02-15'),
    assertEqual(addMonths('2015-01-31', 1), '2015-02-28'),
    assertEqual(addMonths('2016-01-31', 1), '2016-02-29'),
    assertEqual(addMonths('2015-01-01', 11), '2015-12-01'),
    assertEqual(addMonths('2015-01-01', 12), '2016-01-01'),
    assertEqual(addMonths('2015-01-01', 24), '2017-01-01'),
    assertEqual(addMonths('2015-02-28', 12), '2016-02-28'),
    assertEqual(addMonths('2015-03-01', 12), '2016-03-01'),
    assertEqual(addMonths('2016-02-29', 12), '2017-02-28')
);

答案 8 :(得分:2)

由于大多数答案都突出显示,我们可以使用setMonth()方法和getMonth()方法将特定的月份数添加到指定日期。

示例:(正如@ChadD在他的回答中提到的那样。)

var x = 12; //or whatever offset 
var CurrentDate = new Date();
CurrentDate.setMonth(CurrentDate.getMonth() + x);

但我们应该谨慎使用这个解决方案,因为我们会遇到边缘情况的麻烦。

要处理边缘情况,请在以下链接中给出答案是有帮助的。

https://stackoverflow.com/a/13633692/3668866

答案 9 :(得分:2)

只需添加已接受的答案和评论。

var x = 12; //or whatever offset
var CurrentDate = new Date();

//For the very rare cases like the end of a month
//eg. May 30th - 3 months will give you March instead of February
var date = CurrentDate.getDate();
CurrentDate.setDate(1);
CurrentDate.setMonth(CurrentDate.getMonth()+X);
CurrentDate.setDate(date);

答案 10 :(得分:1)

我写了这个替代解决方案,对我来说很好。当您希望计算合同的结束时,它很有用。例如,start = 2016-01-15,months = 6,end = 2016-7-14(即last-1):

<script>
function daysInMonth(year, month)
{
    return new Date(year, month + 1, 0).getDate();
}

function addMonths(date, months)
{
    var target_month = date.getMonth() + months;
    var year = date.getFullYear() + parseInt(target_month / 12);
    var month = target_month % 12;
    var day = date.getDate();
    var last_day = daysInMonth(year, month);
    if (day > last_day)
    {
        day = last_day;
    }
    var new_date = new Date(year, month, day);
    return new_date;
}

var endDate = addMonths(startDate, months);
</script>

示例:

addMonths(new Date("2016-01-01"), 1); // 2016-01-31
addMonths(new Date("2016-01-01"), 2); // 2016-02-29 (2016 is a leap year)
addMonths(new Date("2016-01-01"), 13); // 2017-01-31
addMonths(new Date("2016-01-01"), 14); // 2017-02-28

答案 11 :(得分:0)

所有这些看起来都太复杂了,我想这会引发一场关于究竟在什么时候添加&#34;一个月&#34;手段。这意味着30天?这是从1日到1日吗?从最后一天到最后一天?

如果是后者,那么在2月27日增加一个月就可以到达3月27日,但是到2月28日增加一个月会让你到3月31日(闰年除外,它会让你到3月28日)。然后从3月30日减去一个月让你... 2月27日?谁知道......

对于那些寻找简单解决方案的人来说,只需添加毫秒即可完成。

function getDatePlusDays(dt, days) {
  return new Date(dt.getTime() + (days * 86400000));
}

Date.prototype.addDays = function(days) {
  this = new Date(this.getTime() + (days * 86400000));
};

答案 12 :(得分:0)

正如许多复杂,丑陋的答案所表明的那样,日期和时代对于使用任何语言的程序员来说都是一场噩梦。我的方法是将日期和'delta t'值转换为Epoch Time(以ms为单位),执行任何算术,然后转换回“人类时间”。

// Given a number of days, return a Date object
//   that many days in the future. 
function getFutureDate( days ) {

    // Convert 'days' to milliseconds
    var millies = 1000 * 60 * 60 * 24 * days;

    // Get the current date/time
    var todaysDate = new Date();

    // Get 'todaysDate' as Epoch Time, then add 'days' number of mSecs to it
    var futureMillies = todaysDate.getTime() + millies;

    // Use the Epoch time of the targeted future date to create
    //   a new Date object, and then return it.
    return new Date( futureMillies );
}

// Use case: get a Date that's 60 days from now.
var twoMonthsOut = getFutureDate( 60 );

这是针对略有不同的用例编写的,但您应该能够轻松地将其用于相关任务。

编辑:完整来源here

答案 13 :(得分:0)

以下是如何根据日期输入(membershipssignup_date)+通过表单字段添加月份(membershipsmonths)来计算未来日期的示例。

membershipsmonths字段的默认值为0

触发器链接(可以是附加到成员资格术语字段的onchange事件):

<a href="#" onclick="calculateMshipExp()"; return false;">Calculate Expiry Date</a>

function calculateMshipExp() {

var calcval = null;

var start_date = document.getElementById("membershipssignup_date").value;
var term = document.getElementById("membershipsmonths").value;  // Is text value

var set_start = start_date.split('/');  

var day = set_start[0];  
var month = (set_start[1] - 1);  // January is 0 so August (8th month) is 7
var year = set_start[2];
var datetime = new Date(year, month, day);
var newmonth = (month + parseInt(term));  // Must convert term to integer
var newdate = datetime.setMonth(newmonth);

newdate = new Date(newdate);
//alert(newdate);

day = newdate.getDate();
month = newdate.getMonth() + 1;
year = newdate.getFullYear();

// This is British date format. See below for US.
calcval = (((day <= 9) ? "0" + day : day) + "/" + ((month <= 9) ? "0" + month : month) + "/" + year);

// mm/dd/yyyy
calcval = (((month <= 9) ? "0" + month : month) + "/" + ((day <= 9) ? "0" + day : day) + "/" + year);

// Displays the new date in a <span id="memexp">[Date]</span> // Note: Must contain a value to replace eg. [Date]
document.getElementById("memexp").firstChild.data = calcval;

// Stores the new date in a <input type="hidden" id="membershipsexpiry_date" value="" name="membershipsexpiry_date"> for submission to database table
document.getElementById("membershipsexpiry_date").value = calcval;
}

答案 14 :(得分:0)

这适用于所有边缘情况。 newMonth的怪异计算处理的是负月份输入。如果新的月份与预期的月份不匹配(例如2月31日),则会将月份的日期设置为0,这表示“上个月末”:

function dateAddCalendarMonths(date, months) {
    monthSum = date.getMonth() + months;
    newMonth = (12 + (monthSum % 12)) % 12;
    newYear = date.getFullYear() + Math.floor(monthSum / 12);
    newDate = new Date(newYear, newMonth, date.getDate());
    return (newDate.getMonth() != newMonth)
        ? new Date(newDate.setDate(0))
        : newDate;
}

答案 15 :(得分:0)

我更改了接受的答案以保持原始日期不变,因为我认为应该在这样的函数中使用。

function addMonths(date, months) {
    let newDate = new Date(date);
    var day = newDate.getDate();
    newDate.setMonth(newDate.getMonth() + +months);
    if (newDate.getDate() != day)
        newDate.setDate(0);
    return newDate;
}

答案 16 :(得分:-1)

有时可以通过一个操作员创建日期,例如BIRT参数

我在1个月前做了:

new Date(new Date().setMonth(new Date().getMonth()-1));   

答案 17 :(得分:-1)

addDateMonate : function( pDatum, pAnzahlMonate )
{
    if ( pDatum === undefined )
    {
        return undefined;
    }

    if ( pAnzahlMonate === undefined )
    {
        return pDatum;
    }

    var vv = new Date();

    var jahr = pDatum.getFullYear();
    var monat = pDatum.getMonth() + 1;
    var tag = pDatum.getDate();

    var add_monate_total = Math.abs( Number( pAnzahlMonate ) );

    var add_jahre = Number( Math.floor( add_monate_total / 12.0 ) );
    var add_monate_rest = Number( add_monate_total - ( add_jahre * 12.0 ) );

    if ( Number( pAnzahlMonate ) > 0 )
    {
        jahr += add_jahre;
        monat += add_monate_rest;

        if ( monat > 12 )
        {
            jahr += 1;
            monat -= 12;
        }
    }
    else if ( Number( pAnzahlMonate ) < 0 )
    {
        jahr -= add_jahre;
        monat -= add_monate_rest;

        if ( monat <= 0 )
        {
            jahr = jahr - 1;
            monat = 12 + monat;
        }
    }

    if ( ( Number( monat ) === 2 ) && ( Number( tag ) === 29 ) )
    {
        if ( ( ( Number( jahr ) % 400 ) === 0 ) || ( ( Number( jahr ) % 100 ) > 0 ) && ( ( Number( jahr ) % 4 ) === 0 ) )
        {
            tag = 29;
        }
        else
        {
            tag = 28;
        }
    }

    return new Date( jahr, monat - 1, tag );
}


testAddMonate : function( pDatum , pAnzahlMonate )
{
    var datum_js = fkDatum.getDateAusTTMMJJJJ( pDatum );
    var ergebnis = fkDatum.addDateMonate( datum_js, pAnzahlMonate );

    app.log( "addDateMonate( \"" + pDatum + "\", " + pAnzahlMonate + " ) = \"" + fkDatum.getStringAusDate( ergebnis ) + "\"" );
},


test1 : function()
{
    app.testAddMonate( "15.06.2010",    10 );
    app.testAddMonate( "15.06.2010",   -10 );
    app.testAddMonate( "15.06.2010",    37 );
    app.testAddMonate( "15.06.2010",   -37 );
    app.testAddMonate( "15.06.2010",  1234 );
    app.testAddMonate( "15.06.2010", -1234 );
    app.testAddMonate( "15.06.2010",  5620 );
    app.testAddMonate( "15.06.2010", -5120 );

}

答案 18 :(得分:-1)

最简单的解决方案是:

const todayDate = Date.now();
return new Date(todayDate + 1000 * 60 * 60 * 24 * 30* X); 

其中 X 是我们要添加的月数。

答案 19 :(得分:-3)

var a=new Date();
a.setDate(a.getDate()+5);

如上所述,您可以将月份添加到Date功能。