Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript Leap year date validation

Tags:

javascript

I tried searching for the solution in existing stackoverflow answers but I was not finding a suitable answer...

I have 3fields..

  • Year select
  • Month select
  • Date select

If you select the leap year means, February month date will change to 29 days.. But that still shows the 28 days.. Don't know what problem in my code.

var numDays = {
        '1': 31, '2': 28, '3': 31, '4': 30, '5': 31, '6': 30,
        '7': 31, '8': 31, '9': 30, '10': 31, '11': 30, '12': 31
    };

    function setDays(oMonthSel, oDaysSel, oYearSel)
    {
        var nDays, oDaysSelLgth, opt, i = 1;
        nDays = numDays[oMonthSel[oMonthSel.selectedIndex].value];
        if (nDays == 28 && oYearSel[oYearSel.selectedIndex].value % 4 == 0)
            ++nDays;
        oDaysSelLgth = oDaysSel.length;
        if (nDays != oDaysSelLgth)
        {
            if (nDays < oDaysSelLgth)
                oDaysSel.length = nDays;
            else
                for (i; i < nDays - oDaysSelLgth + 1; i++)
                {
                    opt = new Option(oDaysSelLgth + i, oDaysSelLgth + i);
                    oDaysSel.options[oDaysSel.length] = opt;
                }
        }
        var oForm = oMonthSel.form;
        var month = oMonthSel.options[oMonthSel.selectedIndex].value;
        var day = oDaysSel.options[oDaysSel.selectedIndex].value;
        var year = oYearSel.options[oYearSel.selectedIndex].value;
        oForm.dob.value = month + '/' + day + '/' + year;
    }
    var min = new Date().getFullYear(),
            max = min - 13,
            select = document.getElementById('year');
    for (var i = (min - 100); i <= max; i++) {
        var opt = document.createElement('option');
        opt.value = i;
        opt.innerHTML = i;
        select.appendChild(opt);
    }
    date = document.getElementById('day');
    for (var i = 1; i <= 31; i++) {
        var opt = document.createElement('option');
        opt.value = i;
        opt.innerHTML = i;
        date.appendChild(opt);
    }
    jQuery('.month_sel,.day_sel,.year_sel').selectpicker({
        size: 8
    });

<select class="year_sel common_sel" name="year" id="year" onchange="setDays(month, day, this)">
<option value="">Year</option>
</select>
<select name="month" id="month" onchange="setDays(this, day,year)" class="month_sel common_sel">
<option value="">Month</option>
<option value="1">January</option>
<option value="2">February</option>
<option value="3">March</option>
<option value="4">April</option>
<option value="5">May</option>
<option value="6">June</option>
<option value="7">July</option>
<option value="8">August</option>
<option value="9">September</option>
<option value="10">October</option>
<option value="11">November</option>
<option value="12">December</option>
</select>
<select class="day_sel common_sel" name="day" id="day" onchange="setDays(month, this, year)">
<option value="">Day</option>
</select>
<input type="hidden" name="dob" value="" />
like image 307
Prasath V Avatar asked Aug 09 '16 10:08

Prasath V


3 Answers

This bit is wrong:

if (nDays == 28 && oYearSel[oYearSel.selectedIndex].value % 4 == 0)
    ++nDays;

It's more complex than that. The rule is: If the year is evenly divisible by 4 and either it is not evenly divisible by 100 or it is evenly divisible by 400, it's a leap year.

So

if (nDays == 28) {
    var year = oYearSel[oYearSel.selectedIndex].value;
    if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) {
        nDays = 29;
    }
}

For instance, 2000 was a leap year; that was unusual, 75% of the time centuries aren't (1900 was not, nor will 2100 be).

like image 152
T.J. Crowder Avatar answered Oct 28 '22 01:10

T.J. Crowder


You can just use JavaScript's built-in Date object. Just set it to 29th February for the given year. Then check if it was actually set to February (leap-year), or if it rolled on to March (not a leap-year).

var year = (new Date()).getFullYear();
new Date(year + "-02-29").getMonth() === 1;
like image 40
Whothehellisthat Avatar answered Oct 28 '22 03:10

Whothehellisthat


You can use date object and compute final date of a month and process accordingly:

Sample

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

console.log(getDaysInMonth(2016,1));
console.log(getDaysInMonth(2010,1));
console.log(getDaysInMonth(2000,1));
console.log(getDaysInMonth(2100,1));
like image 39
Rajesh Avatar answered Oct 28 '22 02:10

Rajesh