283

I want to add months to a date in JavaScript.

For example: I am inserting date 06/01/2011 (format mm/dd/yyyy) and now I want to add 8 months to this date. I want the result to be 02/01/2012.

So when adding months, the year may also increase.

Simon Johnson
  • 7,632
  • 5
  • 34
  • 48
Kanak Vaghela
  • 6,120
  • 10
  • 30
  • 36

4 Answers4

342

Corrected as of 25.06.2019:

var newDate = new Date(date.setMonth(date.getMonth()+8));

Old From here:

var jan312009 = new Date(2009, 0, 31);
var eightMonthsFromJan312009  = jan312009.setMonth(jan312009.getMonth()+8);
Daniel Protopopov
  • 5,344
  • 3
  • 20
  • 32
  • 63
    that's not a typo - the Date constructor uses 0 for January, not 1. – Alnitak Apr 13 '11 at 06:19
  • What if for example you add 1 instead of 8? It would display February 31st 2009 would it not? – Will Sampson May 31 '13 at 23:05
  • 2
    @Sampson. No, it will display March 3rd 2009 :) – Cristian Ciocău Aug 22 '13 at 14:10
  • 4
    Check this solution for last days in month ;) – Szorstki May 27 '14 at 12:39
  • 2
    Why do you have to do `new Date` on `jan3120091` twice? Couldn't the second line be `var eight.... = jan312009.setMonth(jan312009.getMonth()+8);`? – Kolob Canyon Jul 13 '16 at 21:33
  • 10
    the setMonth() method mutates the date it's called on so surely you need to do the following to not change jan312009 var jan312009 = new Date(2009, 0, 31); var eightMonthsFromJan312009 = new Date(jan312009.getTime()); eightMonthsFromJan312009.setMonth(jan312009.getMonth()+8); – tazmaniax Jul 04 '17 at 16:27
  • running this code in a REPL sets `eightMonthsFromJan312009` to a number, not a valid date. Calling `jan312009.setMonth(jan312009.getMonth()+8);` changes the variable `jan312009` rather than returning the expected value. – mckeejm Sep 06 '17 at 14:42
  • To run it in REPL one needs to remove var before the declaration of variables. – Daniel Protopopov Sep 06 '17 at 16:33
  • no you don't.. if you use http://repl.it it just takes pure Javascript like what you've pasted. Try it.. see the results. – mckeejm Sep 06 '17 at 19:50
  • This is really not a reusable solution since setMonth can only accept values from 0-11. So you can't add 8 month to April. – Vinayak Thatte Nov 06 '18 at 09:56
  • OP, please change your answer : as @tazmaniax and other people said, the `setMonth()` method does not return a `Date` object, it returns a `Number` representative of the unix timestamp (https://www.w3schools.com/jsref/jsref_setmonth.asp) Therefore, the acceptable answers would be to either remove the new var assignation, or instance a new Date object using the returned timestamp : `var newDate = new Date(date.setMonth(date.getMonth()+8))` – Ghis Jun 25 '19 at 13:34
  • 6
    It's important to emphasize that both `date` and `newDate` will contain the same date after this code is run. IOW `date` is modified by this code. – Roger Feb 13 '20 at 14:34
  • @VinayakThatte it seems that it accepts more than that, please check the [docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setMonth). monthValue: A zero-based integer representing the month of the year offset from the start of the year. So, 0 represents January, 11 represents December, -1 represents December of the previous year, and 12 represents January of the following year. – MhdSyrwan Mar 16 '20 at 09:17
177

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.

mu is too short
  • 396,305
  • 64
  • 779
  • 743
  • 60
    **Careful** - this does not work for edge cases, such as adding to the 31st day of most months. For example, Oct 31 2011 + 1 month using this method is Dec 01 2011 using Javascript's standard Date object. http://jsfiddle.net/KyleMit/jLbbk27v/ – KyleMit Oct 16 '14 at 15:13
  • 1
    @KyleMit Depends on what you expect. – xehpuk Sep 07 '17 at 13:58
  • 7
    @xehpuk, yes, of course, but that is *not* what most people would expect. If I add 1 month, i'd be surprised if the month went from october to december. `10 + 1 != 12` ... if I'm talking about adding 31 days, well sure, that should just be 31 days in the future. Either way, use as is appropriate for your use case, but still take note of the edge cases – KyleMit Sep 07 '17 at 14:04
109

I took a look at the datejs and stripped out the code necessary to add months to a date handling edge cases (leap year, shorter months, etc):

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

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

Date.prototype.isLeapYear = function () { 
    return Date.isLeapYear(this.getFullYear()); 
};

Date.prototype.getDaysInMonth = function () { 
    return Date.getDaysInMonth(this.getFullYear(), this.getMonth());
};

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

This will add "addMonths()" function to any javascript date object that should handle edge cases. Thanks to Coolite Inc!

Use:

var myDate = new Date("01/31/2012");
var result1 = myDate.addMonths(1);

var myDate2 = new Date("01/31/2011");
var result2 = myDate2.addMonths(1);

->> newDate.addMonths -> mydate.addMonths

result1 = "Feb 29 2012"

result2 = "Feb 28 2011"

Jazaret
  • 3,415
  • 3
  • 15
  • 15
  • 6
    Is this the only solution that considers for example this: Oct 31 2011 + 1 ? – chris Sep 26 '13 at 07:11
  • 1
    easier IMHO finding days in month is return new Date(year, month+1, 0).getDate(); So also the need for isLeapYear() falls. Also not clear the need for not-Prototype-Methods – Daniel Nov 14 '14 at 09:43
  • Interesting Daniel that you can put a 0 day to get the previous month. – Jazaret Nov 14 '14 at 17:15
  • 2
    There is a problem with this solution: https://jsfiddle.net/nikoudel/mdzaddeh/ Suppose initial date is "2011-03-11T00:00:00Z" and local timezone is Helsinki (GMT+2). When adding six months, an hour gets lost because of daylight savings time: Sat, 10 Sep 2011 23:00:00 GMT. – Nikolai Koudelia Mar 31 '16 at 10:40
  • See [this response](http://stackoverflow.com/a/36331522/513570) when a non extending prototype solution is needed, as discussed in http://stackoverflow.com/questions/14034180/why-is-extending-native-objects-a-bad-practice – Miquel Mar 31 '16 at 11:03
15

I would highly recommend taking a look at datejs. With it's api, it becomes drop dead simple to add a month (and lots of other date functionality):

var one_month_from_your_date = your_date_object.add(1).month();

What's nice about datejs is that it handles edge cases, because technically you can do this using the native Date object and it's attached methods. But you end up pulling your hair out over edge cases, which datejs has taken care of for you.

Plus it's open source!

Alex
  • 58,815
  • 45
  • 146
  • 176