16

Possible Duplicate:
Javascript function to add X months to a date

I'd like to add 2 months to a user-input end date. How can I add 2 months to the end date and display it?

/**
* Click "Cal" on end date
*/
function getEndDate() {
if(!document.getElementById('startdate').value.length) {
    alert("Start date must be set first.");
}
else {
    prevEndDate = document.getElementById('enddate').value;
    displayCalendar(document.forms[0].enddate,'yyyy/mm/dd',
        document.getElementById('enddatebutton'));
}
}

/**
* Click "Cal" on expiry date
*/
function getExpiryDate() {
if(!document.getElementById('enddate').value.length) {
    alert("End date must be set first.");
}
else {
    prevExpiryDate = document.getElementById('expirydate').value;
    displayCalendar(document.forms[0].expirydate,'yyyy/mm/dd',
        document.getElementById('expirydatebutton'));
 }
}

Any help is appreciated. Thanks!

Community
  • 1
  • 1

2 Answers2

51

You need to get business rules for adding months. The simple solution is:

function addMonths(dateObj, num) {
  return dateObj.setMonth(dateObj.getMonth() + num);
}

However, that will change 31 July to 31 September, which will be converted to 1 October. Also, 31 January plus 1 month is 31 February which will be converted to 2 or 3 March depending on whether it's a leap year or not.

You might expect the first to be 30 September and the second to be 28 or 29 February (depending on whether it's a leap year or not).

So if you want "end of months" be observed, you need to do something like:

function addMonths(dateObj, num) {

    var currentMonth = dateObj.getMonth() + dateObj.getFullYear() * 12;
    dateObj.setMonth(dateObj.getMonth() + num);
    var diff = dateObj.getMonth() + dateObj.getFullYear() * 12 - currentMonth;

    // If don't get the right number, set date to 
    // last day of previous month
    if (diff != num) {
        dateObj.setDate(0);
    } 
    return dateObj;
} 

But check with whoever is responsible for the business rules that that is what they want.

Edit

The above works well, but in response to McShaman's comment here is a version with a simpler check for the month roll–over:

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());
RobG
  • 142,382
  • 31
  • 172
  • 209
  • Does this work? If so... How? What is the `d.getMonth() + d.getFullYear() * 12` code working out? – McShaman Jan 14 '15 at 20:51
  • @McShaman—yes, it adds the required number of months to a date, just fine. – RobG Jan 14 '15 at 23:44
  • The second (simplified) version doesn't work when going back to the previous year. E.g. `addMonths(new Date(2017, 0, 1), -1)` returns _30th Nov 2016_ (while _1st Dec 2017_ was expected). – Jan Šotola Mar 30 '17 at 12:01
  • 1
    @JanŠotola—thanks, fixed. The previous algorithm only worked when adding months. – RobG Mar 30 '17 at 13:32
  • 1
    @JanŠotola you mean *1st Dec 2016* was expected, surely? – shennan Jun 15 '17 at 10:01
  • @shennan: Yes, thanks. Unfornatelly I cannot edit the comment anymore. – Jan Šotola Jun 15 '17 at 15:30
  • @RobG Unrelated question, I am new to JS but was wondering the second `+` in `date.setMonth(date.getMonth() + +months);` isn't required right or is it used to signify a special meaning? – linuxNoob Jan 10 '20 at 15:56
  • 1
    @linuxNoob—in that context it acts as a [*unary + operator*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Unary_plus_2) and converts the operand to number (effectively a shorthand way of writing `Number(months)`). – RobG Jan 10 '20 at 22:11
  • @RobG and you did that because `months` could possibly be a non-Number datatype? – linuxNoob Jan 11 '20 at 06:08
  • @RobG shorthand +months is a nice idea but please change it to Number(months) because it's confusing and most IDE's throw complaints – johnSmith563 Feb 08 '23 at 16:15
0

Split your date into year, month, and day components then use Date:

var d = new Date(year, month, day);
d.setMonth(d.getMonth() + 8);

Date will take care of fixing the year.

Possible Duplicate of How to add months to a date in JavaScript?

Community
  • 1
  • 1
Ravi Kumar
  • 226
  • 2
  • 10
  • Month needs to be `--month` as they're zero indexed in javascript. Also, if you use the above to add 2 months to 31 July you get 31 September, which is converted to 1 October as September only has 30 days. – RobG Oct 09 '12 at 05:09
  • Thanks for making it clear RobG, I appreciate it – Ravi Kumar Oct 09 '12 at 05:11