71

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?

Joe Doyle
  • 6,363
  • 3
  • 42
  • 45

10 Answers10

74

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.

Tom
  • 4,742
  • 25
  • 32
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • Of course, it's worth mentioning that all of this depends on what your computer's date is set to. It's rarely accurate. – Josh Stodola Mar 24 '09 at 00:35
  • Good one, @Josh :-) - mine's not normally out by more than a few minutes. I can't vouch for anyone else. Perhaps I should adjust the answer to read "will give you the first day of the month following **the month your computer thinks it is**. – paxdiablo Mar 24 '09 at 00:47
  • 1
    This solution may not work for zulu time. My increments are off by the time zone diff. – Jess Jan 06 '14 at 21:55
  • 2
    What a coincidence, today is Jan 31st 2017! – SSH This Jan 31 '17 at 17:40
  • 1
    reading Jan 17 2023! This question is timeless. – java-addict301 Jan 17 '23 at 09:18
60

Instead, try:

var now = new Date();
current = new Date(now.getFullYear(), now.getMonth()+1, 1);
Benjamin Oakes
  • 12,262
  • 12
  • 65
  • 83
Brannon
  • 25,687
  • 5
  • 39
  • 44
  • This appears to be working if I do current.getMonth()+1 after using your code. Thanks! –  Feb 01 '09 at 00:16
  • Keep in mind this sets the day of the month back to 1 - is this what you wanted? – paxdiablo Feb 01 '09 at 00:17
  • 1
    All I want to do is get to the next month from the current month. I don't care about the days, I just need the month to be accurate. –  Feb 01 '09 at 00:20
  • 11
    `getYear` is deprecated and won't work properly. Need to use `getFullYear` instead. – kangax Dec 05 '10 at 21:05
  • 1
    How will this work if month is december? Edit: verified that it works by rolling to the next year. – java-addict301 Jan 17 '23 at 09:19
40

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.

Terra Ashley
  • 850
  • 1
  • 10
  • 18
6

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)

Julio
  • 1,903
  • 2
  • 16
  • 19
6

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)
Radha Satam
  • 998
  • 9
  • 11
3

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

<script type="module">
  import { addMonths } from 'https://cdn.jsdelivr.net/npm/date-fns/+esm'; 
  
  const nextMonth = addMonths(new Date(), 1);
  console.log(`Next month is ${nextMonth}`);
</script>
smac89
  • 39,374
  • 15
  • 132
  • 179
  • Nice, wasn't aware of date-fns until now. Have resisted moment.js due to its size, but date-fns is modular and I can just import the functions I need. – Louise Eggleton Apr 11 '21 at 15:02
2

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

Mateo Marin
  • 265
  • 3
  • 8
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);
fthiella
  • 48,073
  • 15
  • 90
  • 106
1

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 

}
Shikha thakur
  • 1,269
  • 13
  • 34
1

here is how i do it:

    getMonthName(offset=0, format="long"){

    /*
    i.e.
    offset: 0     - this month
    offset: -1    - previous month
    offset: 1     - next month

    format: short - Oct
    format: long  - October
     */
    
    const now = new Date();
    const month = new Date(now.getFullYear(), now.getMonth() + offset, 1)
    return month.toLocaleString('default', { month: format })

}
rafalf
  • 425
  • 7
  • 16