319

Possible Duplicate:
What is the best way to determine the number of days in a month with javascript?

Say I have the month as a number and a year.

Brett DeWoody
  • 59,771
  • 29
  • 135
  • 184
Malcolm
  • 12,524
  • 28
  • 89
  • 125

4 Answers4

794
// Month in JavaScript is 0-indexed (January is 0, February is 1, etc), 
// but by using 0 as the day it will give us the last day of the prior
// month. So passing in 1 as the month number will return the last day
// of January, not February
function daysInMonth (month, year) {
    return new Date(year, month, 0).getDate();
}

// July
daysInMonth(7,2009); // 31
// February
daysInMonth(2,2009); // 28
daysInMonth(2,2008); // 29

For the sake of explicit clarity amidst zero-index confusion, here is an interactive example:

function daysInMonth (month, year) {
  return new Date(parseInt(year), parseInt(month) + 1, 0).getDate();
}

//---------- iteraction stuff -----

const byId = (id) => document.getElementById(id);
const monthSelect = byId("month");
const yearSelect = byId("year");

const updateOutput = () => { 
  byId("output").innerText = daysInMonth(monthSelect.value, yearSelect.value)
}
updateOutput();

[monthSelect, yearSelect].forEach((domNode) => { 
  domNode.addEventListener("change", updateOutput)
})
Month: <select id="month">
  <option value="0">Jan</option>
  <option value="1">Feb</option>
  <option value="2">Mar</option>
  <option value="3">Apr</option>
  <option value="4">May</option>
  <option value="5">Jun</option>
  <option value="6">Jul</option>
  <option value="7">Aug</option>
  <option value="8">Sep</option>
  <option value="9">Oct</option>
  <option value="10">Nov</option>
  <option value="11">Dec</option>
</select>
<br>
Year: <select id="year">
  <option value="2000">2000 (leap year)</option>
  <option value="2001">2001</option>
  <option value="2002">2002</option>
  <option value="2003">2003</option>
</select>
<br>

Days in month: <span id="output"></span>
Seph Reed
  • 8,797
  • 11
  • 60
  • 125
  • 57
    in Javascript months a 0-based, so while this seems right it is inconsistent with other javascript functions – Greg Jul 26 '09 at 11:43
  • 3
    Right. So use my function if you're parsing user input and soulscratch's function if you're using programmatic input. –  Jul 26 '09 at 12:30
  • 14
    @SamGoody, if your month input to daysInMonth is 1-based the function seems to work just fine. That is, e.g. June = 6. – agibsen May 14 '12 at 13:19
  • 16
    The point of using `0` as the day is that it returns the last day of the last month, so you have to add `1` to it to return the correct amount of days when using `month = new Date().getMonth()` – Charlie Jan 17 '13 at 00:42
  • For those of you who are trying to decrement months, then use -1 instead of 0 and that works the same. – marksyzm Jul 04 '14 at 10:37
  • 1
    Why is the third argument necessary? – TaylorMac Jul 29 '14 at 15:48
  • 4
    So everyone who's wondering why new Date(2012, 5, 0).getDate() returns 31.. the 5th month (1 based) is may and not june – tObi Oct 20 '14 at 15:57
  • nice solution, this should be marked as the answer since it's the first result to google search. – Victor Ivens Aug 14 '15 at 18:50
  • It is wrong, months are 0 based – Bogdan M. Oct 06 '15 at 17:55
  • 48
    I found this a bit confusing, so to clarify in case it helps anyone: For the Javascript Date function, the second argument is month, starting with 0. The third argument is day, starting with 1. When you pass a 0 to the third argument instead, it uses the last day of the previous month. If you were to pass -1 as the third argument, it would be the second to last day of the previous month (it's decrementing). This is why this works, but the month has to start with 1 instead of 0 as is normal with Javascript dates, because it's actually switching to the previous month because the day number is 0. – Allan Wintersieck Jul 15 '16 at 15:16
  • 1
    Based on this comments, I edited the javascript comment in the answer to make it less confusing. – sandre89 Mar 27 '18 at 02:40
  • Does this work for December if months are 0 - 11? Can I pass in 12?? – Matt Nov 28 '18 at 14:01
  • 1
    @Matt Yes, you can. The 0-indexed 12th month of a year is January of the next year, so it works just as intended. – Meshaal Feb 18 '19 at 06:46
  • 1
    Here is the same implementation, but expanded to make the conversion between 1-indexed months and 0-indexed months more explicit: https://gist.github.com/TehShrike/6a27b28160bad1e3ccd98e2ee3ea752c – TehShrike Jan 10 '20 at 19:45
  • Please add a more clear note about `getMonth` being 0 based index at the top. This helps a lot of people catching the bug earlier. – Amir Apr 04 '23 at 07:57
143
Date.prototype.monthDays= function(){
    var d= new Date(this.getFullYear(), this.getMonth()+1, 0);
    return d.getDate();
}
kennebec
  • 102,654
  • 32
  • 106
  • 127
  • 10
    From what I understand, `new Date(year, month, 0)` will produce the last month's last day, so adding `+ 1` to the parameters results in the current month's days. I'm not correcting anything here. I'm trying to make sure I understand, and I believe kennebec's answer here is the correct answer. – Brent Apr 13 '16 at 04:41
  • 1
    @Brent you understood it correctly. Also this function respects Javscript months being 0-based which is nice and convenient – Aides Apr 15 '16 at 08:48
  • 9
    This is the correct answer, not the above one. – Shawn Jun 26 '16 at 17:26
48

The following takes any valid datetime value and returns the number of days in the associated month... it eliminates the ambiguity of both other answers...

 // pass in any date as parameter anyDateInMonth
function daysInMonth(anyDateInMonth) {
    return new Date(anyDateInMonth.getFullYear(), 
                    anyDateInMonth.getMonth()+1, 
                    0).getDate();}
Biruk Abebe
  • 2,235
  • 1
  • 13
  • 24
Charles Bretana
  • 143,358
  • 22
  • 150
  • 216
  • 1
    Throws error when i call it: daysInMonth(new Date()). – CyberFox May 23 '14 at 21:04
  • Yep, just change `++anyDateInMonth.getMonth()` to `anyDateInMonth.getMonth() + 1` – rescuecreative Mar 12 '15 at 19:38
  • @rescuecreative, would it work like this: `++(anyDateInMonth.getMonth()) ` ?? – Charles Bretana Mar 12 '15 at 22:06
  • 2
    @CharlesBretana No, the problem is that your increment operator is causing a reference error. When you use `++` JavaScript is expecting you to be using it to increment a mutable value such as one stored in a variable. For example you can't do `++5` but you can do `var x = 5; ++x`. So in your function, if you don't want to use a variable, you'll have to actually add 1. – rescuecreative Mar 13 '15 at 17:53
  • Neat trick doing day 0 of the next month = last day of current month. I'm surprised this works for December as there is no month after December, unless it wraps around to the next year. – user3015682 Aug 24 '19 at 01:41
  • 1
    Yes it wraps to Jan next year. – Charles Bretana Aug 26 '19 at 13:30
  • in December you need to increment the year – Sergei Aug 13 '23 at 09:16
  • Why? The only reason the year needs to be there is to handle when it's February in a leap year. – Charles Bretana Aug 13 '23 at 13:32
12

Another possible option would be to use Datejs

Then you can do

Date.getDaysInMonth(2009, 9)     

Although adding a library just for this function is overkill, it's always nice to know all the options you have available to you :)

yckart
  • 32,460
  • 9
  • 122
  • 129
RYFN
  • 2,939
  • 1
  • 29
  • 40
  • 19
    here's the function they use in Datejs: return [31, ($D.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]; – CyberFox May 23 '14 at 20:59
  • and what is `isLeapYear`? (It's not a built-in function) – Aidin Nov 14 '21 at 04:22