11

I have a HTML page with 3 dropdowns for the month, day and year and I was wondering if there was a way to populate the month drop down properly depending on the month and year.

I haven't done this before on the client side, but it looks like a lot of controls like the jQuery DatePicker are doing that behind the scenes.

Dyrandz Famador
  • 4,499
  • 5
  • 25
  • 40
Abe
  • 6,386
  • 12
  • 46
  • 75
  • 1
    Possible duplicate: [Repopulating dates on select boxes](http://stackoverflow.com/questions/4822550/repopulating-dates-on-select-boxes) – David Tang Feb 03 '11 at 01:50
  • Thanks Box9! That is actually what I was looking for. – Abe Feb 03 '11 at 01:54

9 Answers9

30

As far as I know, there's no (neat) built-in function for that. I wrote this once:

// note that month is 0-based, like in the Date object. Adjust if necessary.
function getNumberOfDays(year, month) {
    var isLeap = ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0));
    return [31, (isLeap ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
}
Matti Virkkunen
  • 63,558
  • 9
  • 127
  • 159
18

You can play with date objects:

var monthStart = new Date(year, month, 1);
var monthEnd = new Date(year, month + 1, 1);
var monthLength = (monthEnd - monthStart) / (1000 * 60 * 60 * 24)

Arithmetic with Date objects gives a number of milliseconds.

This will even work for December; the Date constructor handles out-of-range arguments by wrapping around.

Note that month is zero-based (it must be between 0 and 11)

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • This is awesome.. it even works on leap years. I tried 2/2012. thanks! – Abe Feb 03 '11 at 02:13
  • 2
    I wrapped it as `var DaysInMonth = function(year, month) { /* SLAK's code here */; return monthLength;};` and further added a prototype method to Date `Date.prototype.daysInMonth = function() { var mlen=DaysInMonth(this.getFullYear(), this.getMonth()); return mlen; };` so I can call `(new DateTime(2000, 1)).daysInMonth();` – John K Feb 03 '11 at 02:56
  • March 2014 returns 30.958333333333332 for some reason. – o01 May 08 '14 at 10:34
  • To avoid decimal numbers, add `Math.round` to monthLength: `monthLength = Math.round( (monthEnd - monthStart) / (1000 * 60 * 60 * 24) );` – bdurao Nov 19 '14 at 17:52
  • 1
    Some months have 1 extra hour or one less hour due to daylight savings. The `(1000 * 60 * 60 * 24)` part of the equation doesn't account for this variance. Rounding will help. – Troy Morehouse Apr 17 '17 at 16:07
3

Copy from another post: Get number days in a specified month using javascript?

//Month is 1 based
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

All the credits to @c_harm, really great solution

Community
  • 1
  • 1
David Sánchez
  • 544
  • 8
  • 21
2
Date.prototype.daysinMonth: function(){
    var d= new Date(this.getFullYear(), this.getMonth()+1, 0);
    return d.getDate();
}

function daysinMonthfromInput(month,year){
    return (new Date(year,month-1,1)).daysinMonth();
}

alert(daysinMonthfromInput(2,2011));
kennebec
  • 102,654
  • 32
  • 106
  • 127
1

Here's the one liner. Assuming you are saying January=1, February=2 etc..(being normal) Here's the leap year example:

var y = 2012;
var m = 2;
var daysInMonth = new Date(y,m,1,-1).getDate();
Adam
  • 359
  • 3
  • 5
0

I am using this approach in my current project and found that I needed correct for round off errors. So instead of using monthLength in my code, I had to use this instead:

monthLength.toFixed(0)

For example if I have an object in which I am storing a text date field, it may look like this:

obj.month = theMonths[mm - 1] + " " + monthLength.toFixed(0) + ", " + obj.year;
user3018981
  • 236
  • 2
  • 10
0

You can actually use this:

var curdate = new Date(); DaysMonth = 32 - new Date(curdate.getYear(), curdate.getMonth(), 32).getDate();

;)

reynan
  • 1
0

This is a possible improvement to the answer given by @MattiVirkkunen:

If you are interested in squeezing every ounce of efficiency from this calculation you should turn this inside out, handling all 'not February' cases first which avoids leap year calculations when the month is not February (11/12 of the time). You can also code it inline which avoids expensive function linkages.

month!=2 ? [31,28,31,30,31,30,31,31,30,31,30,31][month]
         : (year%4!=0 ? 28 : (year%100!=0 : 29 (year%400!=0 ? 28 : 29)));
Chris Maurer
  • 2,339
  • 1
  • 9
  • 8
-2
Date.prototype.daysinMonth= function(){
var d= new Date(this.getFullYear(), this.getMonth()+1, 0);
return d.getDate();
};

function daysinMonthfromInput  (month, year) {
     return (new Date(year, month - 1, 1)).daysinMonth();
};
function fillallday (elem, month, year) {
     var options = null;
     var elementExists = document.getElementById(elem);

     if (elementExists != null) {

         this.removeOptions(elementExists);
         var opt = document.createElement('option');
         opt.value = "";
         opt.innerHTML = "---Day---";
         elementExists.appendChild(opt);
         if (month != "") {
             if (typeof (year) === "undefined") {
                 year = new Date().getFullYear();
             }
             if (year == "") {
                 year = new Date().getFullYear();
             }
             var days = daysinMonthfromInput(month, year);
             for (var i = 1; i <= days; i++) {
                 var opt = document.createElement('option');
                 opt.value = i;
                 opt.innerHTML = i;
                 elementExists.appendChild(opt);
             }
         }
     }

 }