How to add months to a date in JavaScript? [duplicate]
Asked Answered
T

3

382

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.

Threat answered 13/4, 2011 at 6:3 Comment(10)
If, you add 8 months to the date 06/01/2011 how it will be changed to 02/01/2011, Please can you make it some what clearMarplot
this is a hard problem to get right - what happens if you're on the 31st of a month and the target month doesn't have 31 days? Even worse, what if the target month is February?Blowpipe
@kalyan : if I add 8 months to the date 06/01/2011(mm/dd/yyyy) then it will be 02/01/2012 because if we add 06+08 = 14 and we have only 12 months so it will change the year and give the result as 02/01/2012.Threat
@Blowpipe : No dear it will only start with 1st date of month.Threat
then you should have said so....Blowpipe
I suggest adding days instead of months. if you add one month to 30.01.2011 what would the result be? 30.02.2011 ? 02.03.2011 ?Geof
@Blowpipe : I have already maintain that in the my question...Threat
no, you didn't. The fact that the dates in your question are all the 1st would be taken by most as an example, and not a constraint. You even said so: "For example:".Blowpipe
var month = new Date(someDate).getMonth() + 1;Toothbrush
Just encountered this issue today, in case the day of the date is between 1 - 28 (where we know for sure the next month has these days) you can just use setMonth(currentMonth + 1), else use Luxon or any other Date replacement because it won't work otherwise (unless you do parsing on the backend, because JS zero-month based dates is going to screw you)Kinematograph
V
491

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);
Vellum answered 13/4, 2011 at 6:11 Comment(16)
that's not a typo - the Date constructor uses 0 for January, not 1.Blowpipe
What if for example you add 1 instead of 8? It would display February 31st 2009 would it not?Gropius
@Sampson. No, it will display March 3rd 2009 :)Presocratic
Check this solution for last days in month ;)Snaffle
Why do you have to do new Date on jan3120091 twice? Couldn't the second line be var eight.... = jan312009.setMonth(jan312009.getMonth()+8);?Manchineel
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);Furring
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.Mattins
To run it in REPL one needs to remove var before the declaration of variables.Vellum
no you don't.. if you use repl.it it just takes pure Javascript like what you've pasted. Try it.. see the results.Mattins
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.Lasso
OP, please change your answer : as @Furring and other people said, the setMonth() method does not return a Date object, it returns a Number representative of the unix timestamp (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))Egerton
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.Textile
@VinayakThatte it seems that it accepts more than that, please check the docs. 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.Bandsman
error "date" as shown in lowercase is nothing in JSTurgor
adding 1 month to 31 of January dives you 3 March is it OK?Stolen
Gives Invalid date error when the added months sum to > 12Siobhan
B
132

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"

Bonitabonito answered 29/11, 2012 at 19:58 Comment(5)
Is this the only solution that considers for example this: Oct 31 2011 + 1 ?Furbish
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-MethodsLackaday
Interesting Daniel that you can put a 0 day to get the previous month.Bonitabonito
There is a problem with this solution: 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.Exotoxin
See this response when a non extending prototype solution is needed, as discussed in #14034680Scharf
G
19

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!

Grained answered 13/4, 2011 at 6:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.