[javascript] Javascript Date: next month

I've been using Javascript's Date for a project, but noticed today that my code that previously worked is no longer working correctly. Instead of producing Feb as expected, the code below produces March.

My code looks something like this:

current = new Date();
current.setMonth(current.getMonth()+1); //If today is Jan, expect it to be Feb now

This code worked everyday up until today. Is this a Javascript bug or am I going about this the wrong way?

This question is related to javascript date

The answer is


You'll probably find you're setting the date to Feb 31, 2009 (if today is Jan 31) and Javascript automagically rolls that into the early part of March.

Check the day of the month, I'd expect it to be 1, 2 or 3. If it's not the same as before you added a month, roll back by one day until the month changes again.

That way, the day "last day of Jan" becomes "last day of Feb".

EDIT:

Ronald, based on your comments to other answers, you might want to steer clear of edge-case behavior such as "what happens when I try to make Feb 30" or "what happens when I try to make 2009/13/07 (yyyy/mm/dd)" (that last one might still be a problem even for my solution, so you should test it).

Instead, I would explicitly code for the possibilities. Since you don't care about the day of the month (you just want the year and month to be correct for next month), something like this should suffice:

var now = new Date();
if (now.getMonth() == 11) {
    var current = new Date(now.getFullYear() + 1, 0, 1);
} else {
    var current = new Date(now.getFullYear(), now.getMonth() + 1, 1);
}

That gives you Jan 1 the following year for any day in December and the first day of the following month for any other day. More code, I know, but I've long since grown tired of coding tricks for efficiency, preferring readability unless there's a clear requirement to do otherwise.


You may probably do this way

var currentMonth = new Date().getMonth();

var monthNames = ["January", "February", "March", "April", "May", "June",
  "July", "August", "September", "October", "November", "December"
];

for(var i = currentMonth-1 ; i<= 4; i++){
console.log(monthNames[i])// make it as an array of objects here 

}

You can use the date.js library:

http://code.google.com/p/datejs/

And just do this

Date.today().next().month();

You will have the exact value for today + 1 month (including days)


You may probably do this way

var currentMonth = new Date().getMonth();

var monthNames = ["January", "February", "March", "April", "May", "June",
  "July", "August", "September", "October", "November", "December"
];

for(var i = currentMonth-1 ; i<= 4; i++){
console.log(monthNames[i])// make it as an array of objects here 

}

If you use moment.js, they have an add function. Here's the link - https://momentjs.com/docs/#/manipulating/add/

moment().add(7, 'months');

I also wrote a recursive function based on paxdiablo's answer to add a variable number of months. By default this function would add a month to the current date.

function addMonths(after = 1, now = new Date()) {
        var current;
        if (now.getMonth() == 11) {
            current = new Date(now.getFullYear() + 1, 0, 1);
        } else {
            current = new Date(now.getFullYear(), now.getMonth() + 1, 1);            
        }
        return (after == 1) ? current : addMonths(after - 1, new Date(now.getFullYear(), now.getMonth() + 1, 1))
    }

Example

console.log('Add 3 months to November', addMonths(3, new Date(2017, 10, 27)))

Output -

Add 3 months to November Thu Feb 01 2018 00:00:00 GMT-0800 (Pacific Standard Time)

Instead, try:

var now = new Date();
current = new Date(now.getFullYear(), now.getMonth()+1, 1);

try this:

var a = screen.Data.getFullYear();
var m = screen.Data.getMonth();
var d = screen.Data.getDate();

m = m + 1;
screen.Data = new Date(a, m, d);

if (screen.Data.getDate() != d)
screen.Data = new Date(a, m + 1, 0);

ah, the beauty of ternaries:

const now = new Date();
const expiry = now.getMonth() == 11 ? new Date(now.getFullYear()+1, 0 , 1) : new Date(now.getFullYear(), now.getMonth() + 1, 1);

just a simpler version of the solution provided by @paxdiablo and @Tom


try this:

var a = screen.Data.getFullYear();
var m = screen.Data.getMonth();
var d = screen.Data.getDate();

m = m + 1;
screen.Data = new Date(a, m, d);

if (screen.Data.getDate() != d)
screen.Data = new Date(a, m + 1, 0);

Instead, try:

var now = new Date();
current = new Date(now.getFullYear(), now.getMonth()+1, 1);

I was looking for a simple one-line solution to get the next month via math so I wouldn't have to look up the javascript date functions (mental laziness on my part). Quite strangely, I didn't find one here.

I overcame my brief bout of laziness, wrote one, and decided to share!

Solution:

(new Date().getMonth()+1)%12 + 1

Just to be clear why this works, let me break down the magic!

It gets the current month (which is in 0..11 format), increments by 1 for the next month, and wraps it to a boundary of 12 via modulus (11%12==11; 12%12==0). This returns the next month in the same 0..11 format, so converting to a format Date() will recognize (1..12) is easy: simply add 1 again.

Proof of concept:

> for(var m=0;m<=11;m++) { console.info( "next month for %i: %i", m+1, (m+1)%12 + 1 ) }
next month for 1: 2
next month for 2: 3
next month for 3: 4
next month for 4: 5
next month for 5: 6
next month for 6: 7
next month for 7: 8
next month for 8: 9
next month for 9: 10
next month for 10: 11
next month for 11: 12
next month for 12: 1

So there you have it.


Instead, try:

var now = new Date();
current = new Date(now.getFullYear(), now.getMonth()+1, 1);

ah, the beauty of ternaries:

const now = new Date();
const expiry = now.getMonth() == 11 ? new Date(now.getFullYear()+1, 0 , 1) : new Date(now.getFullYear(), now.getMonth() + 1, 1);

just a simpler version of the solution provided by @paxdiablo and @Tom


If you are able to get your hands on date-fns library v2+, you can import the function addMonths, and use that to get the next month

_x000D_
_x000D_
<script type="module">
  import { addMonths } from 'https://cdn.jsdelivr.net/npm/date-fns/+esm'; 
  
  const current = new Date();
  const nextMonth = addMonths(current, 1);
  console.log(`Next month is ${nextMonth}`);
</script>
_x000D_
_x000D_
_x000D_


If you use moment.js, they have an add function. Here's the link - https://momentjs.com/docs/#/manipulating/add/

moment().add(7, 'months');

I also wrote a recursive function based on paxdiablo's answer to add a variable number of months. By default this function would add a month to the current date.

function addMonths(after = 1, now = new Date()) {
        var current;
        if (now.getMonth() == 11) {
            current = new Date(now.getFullYear() + 1, 0, 1);
        } else {
            current = new Date(now.getFullYear(), now.getMonth() + 1, 1);            
        }
        return (after == 1) ? current : addMonths(after - 1, new Date(now.getFullYear(), now.getMonth() + 1, 1))
    }

Example

console.log('Add 3 months to November', addMonths(3, new Date(2017, 10, 27)))

Output -

Add 3 months to November Thu Feb 01 2018 00:00:00 GMT-0800 (Pacific Standard Time)

You can use the date.js library:

http://code.google.com/p/datejs/

And just do this

Date.today().next().month();

You will have the exact value for today + 1 month (including days)


I was looking for a simple one-line solution to get the next month via math so I wouldn't have to look up the javascript date functions (mental laziness on my part). Quite strangely, I didn't find one here.

I overcame my brief bout of laziness, wrote one, and decided to share!

Solution:

(new Date().getMonth()+1)%12 + 1

Just to be clear why this works, let me break down the magic!

It gets the current month (which is in 0..11 format), increments by 1 for the next month, and wraps it to a boundary of 12 via modulus (11%12==11; 12%12==0). This returns the next month in the same 0..11 format, so converting to a format Date() will recognize (1..12) is easy: simply add 1 again.

Proof of concept:

> for(var m=0;m<=11;m++) { console.info( "next month for %i: %i", m+1, (m+1)%12 + 1 ) }
next month for 1: 2
next month for 2: 3
next month for 3: 4
next month for 4: 5
next month for 5: 6
next month for 6: 7
next month for 7: 8
next month for 8: 9
next month for 9: 10
next month for 10: 11
next month for 11: 12
next month for 12: 1

So there you have it.