6
votes

I have three inputs which are for the Day, Month and Year.

<div id="birthday">
    <div>
        <label for="day">Day</label>
        <input type="number" id="day" placeholder="Day" name="day" ref="day" />
    </div>
    <div>
        <label for="month">Month</label>
        <input type="number" id="month" placeholder="Month" name="month" ref="month" />
    </div>
    <div>
        <label for="year">Year</label>
        <input type="number" id="year" placeholder="Year" name="year" ref="year" />
    </div>
    <span class="clear_both"></span>
</div>

I want to validate date by the following:

  1. Year

    • Year should have 4 characters (i.e., YYYY)
    • Year should be between 1900 to present year.
  2. Month

    • Month should be between 1 to 12
  3. Day

    • If the year is a leap year and month is 2 (february) then Day should be between 1 to 29
    • If the year is not a leap year, then the Day should be between 1 to 31 or 1 to 30 depending on the month

I can only check the month and year:

let day = this.refs.day.value
let month = this.refs.month.value
let year = this.refs.year.value
let errors = []

if (!((year.length == 4) && (year > 1900 && year < 2016))) {
    errors.push("year");
}
if (!(month > 0 && month < 13)) {
    errors.push("month");
}

How can I make this work in javascript? Could you please help me. Thank you.

2
@RobG That's even better. Thank you.Karl

2 Answers

2
votes

Answering my own question here. Andrea's answer pointed me to the right direction. Although there was a bug, which I cleared in this answer. The bug was, if the month was greater than list of items in monthLength it would was going to make the day to wrong. Also changed to check if days is in between 1 to total days for that selected month. So here's the full script:

let day = this.refs.day.value
let month = this.refs.month.value
let year = this.refs.year.value
var monthLength = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ];
var total_days = 0;

// Adjust for leap years
if(year % 400 == 0 || (year % 100 != 0 && year % 4 == 0))
    monthLength[1] = 29;

let errors = []

console.log('total_days = ' + total_days);

if (!((year.length == 4) && (year > 1900 && year < 2016))) {
    errors.push("year");
}

if (!(month > 0 && month < 13)) {
    errors.push("month");
    total_days = monthLength[0];
}
else {
    total_days = monthLength[month - 1];
}

if (!(day > 0 && day <= total_days)) {
    errors.push("day");
}
1
votes

Similar to user3817980, and based on this question but built into your code, see below.

I am also checking that the day is not negative, which might be an overkill but does not harm.

let day = this.refs.day.value
let month = this.refs.month.value
let year = this.refs.year.value
var monthLength = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ];

// Adjust for leap years
if(year % 400 == 0 || (year % 100 != 0 && year % 4 == 0))
    monthLength[1] = 29;

let errors = []

if (!((year.length == 4) && (year > 1900 && year < 2016))) {
    errors.push("year");
}

if (!(month > 0 && month < 13)) {
    errors.push("month");
}

if (day < 0 || day > monthLength[month - 1]) {
    errors.push("day");
}