Programmer
Programmer

Reputation: 8717

Year of date validation is failing

I need to do a date validation to accept it in dd/mm/yyyy format. However all conditions are working fine except that if I enter year of 6 digits it is also accepting it, like -

12/12/200000

as per my code is valid. Below is my code:

function validate(value) {
            if(!value.match(/\d\d\/\d\d\/\d\d\d\d/))
                return false;
            return checkdate(value);
}

function checkdate(val)
{
    var dates = val.split(/\D/);
    if(dates[0] <= 0 || dates[0] > 31)
        return false;
    if(dates[1] <= 0 || dates[1] > 12)
        return false;
    var now = new Date(dates[2],dates[1]-1,dates[0]);
    if (isNaN(now))
        return false;
    now.setHours(0,0,0,0);
    if (now.getFullYear() == dates[2] && now.getMonth() + 1 == dates[1] && now.getDate() == dates[0])
        return true;
    return false;
}

I am not sure why it allowing year as 6 digits valid input?

Upvotes: 2

Views: 60

Answers (3)

RobG
RobG

Reputation: 147453

If you want to validate a date string by creating a Date object, you don't need to check the entire pattern, just create and Date and check the result. Do you really need two digits for day and month number?

If you want a 4 digit year, that must be checked separately as the constructor will happily convert two digit years to 20th century. If you really need two digit day and month, that can be checked at the same time as the year:

function validateDMY(s) {
  var b = s.split(/\D/);
  var d = new Date(b[2], --b[1], b[0]);
  return d && /^\d{4}$/.test(b[2]) && b[1] == d.getMonth();
}

console.log(validateDMY('30/02/2015')); // false
console.log(validateDMY('30/22/2015')); // false
console.log(validateDMY('02/02/15'));   // false
console.log(validateDMY('30/01/2015')); // true

Upvotes: 0

The problem is in validate function, regular expression it matches against allows input values you don't want to pass as valid. Besides obvious dd/mm/yyyy format, it allows found text to be anywhere in string. Basically, you said for it to check "if there's said expression inside string", when it should have been "if the whole string matches this expression".

To fix the issue, add ^ at the beginning and $ at the end. ^ stands for string start and $ for string end:

/^\d\d\/\d\d\/\d\d\d\d$/

I think you would benefit from reading documentation on regular expression syntax used by JavaScript.

While at at, humans tend to have issues reading long repeating sequences of similar characters, like in your regexp. This expression is easer to understand and does exactly the same thing:

/^\d{2}\/\d{2}\/\d{4}$/

Upvotes: 2

adeneo
adeneo

Reputation: 318302

You're not limiting the regex with start and stop delimiters, so 12/12/200000 is a match as it matched the regex, and then some

if (!value.match(/^\d\d\/\d\d\/\d\d\d\d$/) )

As a sidenote, you don't have to type \d four times, you can do \d{4} to match four instances of \d

Upvotes: 1

Related Questions