simon
simon

Reputation: 13

Javascript incorrectly validating a date

I wrote a function to check if a date is valid

I wrote all except one small part

The function does not work and I cannot find the error, can you kindly help?

I can see that because the number 29 is not in the array it's not working however am confuddled how to get it to work

function isValidDate() {
  var dateformat = /^(0?[1-9]|[12][0-9]|3[01])[-](0?[1-9]|1[012])[-]\d{4}$/;

  var readDate = document.getElementById("myDate").value;

  if (readDate.length <= 10) {
    <!--debug-->
    //console.log(readDate);

    /* split date into DD-MM-YYYY format */
    var splitDate = readDate.split('-');

    var day = splitDate[0];

    var month = splitDate[1];

    var year = splitDate[2];

    /* DEBUG - print split date into DD-MM-YYYY format */
    console.log('day ' + day);
    console.log('month ' + month);
    console.log('year ' + year);

    // Create list of days of a month [assume there is no leap year by default]  
    var ListofDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

    //if month is between 1-12
    if (month == 1 || month < 13) {
      //check for invalid month
      if (month == 00) {
        console.log('0 - Invalid MONTH format!');
        return 0;
      }

      //check for invalid day
      if (day == 00) {
        console.log('0 - Invalid DAY format!');
        return 0;
      }

      //check DAY exists in the MONTH
      if (day > ListofDays[month - 1]) {
        console.log('1 - Invalid DATE format!');
        return 0;
      } else {
        console.log('1 - Valid DATE format!');
        return 1
      }
    } else {
      console.log("Invalid MONTH");
      return 0;
    }

    //check for leap year
    if (year % 4 === 0 && year % 100 !== 0) {
      console.log('The year ' + year + ' is a leap year.');
      return 1;
    } else if (year % 4 === 0 && year % 100 === 0 && year % 400 === 0) {
      console.log('The year ' + year + ' is a leap year.');
      return 1;
    } else {
      console.log('The year ' + year + ' is NOT a leap year');
      return 0;
    }
  } else {
    console.log("Invalid DATE length")
  }
}


/*    This is the only bit I did not write:
    
    	if (day > ListofDays[month-1])  
    	{  
        console.log('1 - Invalid DATE format!');  
        return 0;  
    	} 
    	else
        {
        console.log('1 - Valid DATE format!');  
        return 1
    }

*/
<p>Input a date and check it's in a)correct format and b)it is a valid date</p>

<input type="text" id="myDate" placeholder="DD-MM-YYYY"> <br><br>

<button type="button" onclick="isValidDate()"> Check Date </button>

Upvotes: 1

Views: 86

Answers (3)

mplungjan
mplungjan

Reputation: 177885

  1. Test the date against the regex you have to reduce the tests
  2. do NOT return when you want to continue

Here is a solution that keeps the code as close to what you want to do as possible. The simpler solution using a Date Object I already suggested in a comment and has been elaborated on by others

function showError(str) {
  console.log(str)
  return false;
}

function isValidDate() {
  var dateformat = /^(0?[1-9]|[12][0-9]|3[01])[-](0?[1-9]|1[012])[-]\d{4}$/;

  var readDate = document.getElementById("myDate").value;

  if (readDate.length != 10) return showError("Invalid DATE length") // not correct length
  console.log(dateformat.test(readDate));

  if (!dateformat.test(readDate)) {
    return showError("Invalid DATE format") // not matching regex
  }

  /* split date into DD-MM-YYYY format */
  var splitDate = readDate.split('-');

  var day = splitDate[0];
  var month = splitDate[1];
  var year = splitDate[2];

  /* DEBUG - print split date into DD-MM-YYYY format */
  console.log('day ' + day);
  console.log('month ' + month);
  console.log('year ' + year);

  // Create list of days of a month [assume there is no leap year by default]  
  var ListofDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

  //if month is not between 1-12
  if (month <= 0 || month > 12) {
    return showError('0 - Invalid MONTH format!');
  }

  var isLeap = false;
  //check for leap year
  if (year % 4 === 0 && year % 100 !== 0) {
    console.log('The year ' + year + ' is a leap year.');
    isLeap = true;
  } else if (year % 4 === 0 && year % 100 === 0 && year % 400 === 0) {
    console.log('The year ' + year + ' is a leap year.');
    isLeap = true;
  } else {
    console.log('The year ' + year + ' is NOT a leap year');
  }

  //check DAY exists in the MONTH
  var testDay = ListofDays[month - 1]; // array starts at 0
  // testDay += isLeap ? 1 : 0; // add one to testDay using ternary operator
  if (isLeap) testDay++; // less code, does the same as above
  if (day > testDay) {
    return showError('1 - Invalid DATE format!');
  }

  console.log('1 - Valid DATE format!');
  // You can return true here if you want


}
<p>Input a date and check it's in a)correct format and b)it is a valid date</p>

<input type="text" id="myDate" placeholder="DD-MM-YYYY"> <br><br>

<button type="button" onclick="isValidDate()"> Check Date </button>

Upvotes: 1

Laurianti
Laurianti

Reputation: 975

function validate(value) {
  var v = false;
  if (value) {
    var r = value.match(/([0-9]{1,2}).?([0-9]{1,2}).?([0-9]{4})/);
    
    if (r) {
      var day1 = parseInt(r[1]);
      var month1 = parseInt(r[2]);
      var year1 = parseInt(r[3]);

      var d = new Date(year1, month1 - 1, day1);

      var day2 = d.getDate();
      var month2 = d.getMonth() + 1;
      var year2 = d.getFullYear();

      v = day1    == day2   &&
          month1  == month2 &&
          year1   == year2;
    }
  }
  
  return v;
}
<input type="text" id="toCheck" />
<button onclick="console.log(validate(document.getElementById('toCheck').value))">Check</button>

You can try with any separator, this is only an example (I used a trick to check a real date). You can modify this function for your personal use.

Upvotes: 0

Niet the Dark Absol
Niet the Dark Absol

Reputation: 324630

Discard all that.

<input type="date" />

Job done.


Alternatively, since you're specifying the format you can do something like this:

var input = document.getElementById("myDate").value;
var parts = input.split("-");
var date = new Date(parts[2],parts[1]-1,parts[0]);
return date.getFullYear() == parts[2]
    && date.getMonth() == parts[1]-1
    && date.getDate() == parts[0];

This works because JavaScript will "fix" the date if it falls outside of valid bounds (eg. January 32nd is corrected to February 1st), so just check to see if it changed anything when it received the date.

Upvotes: 0

Related Questions