willis0924
willis0924

Reputation: 67

Javascript Regular Expression to validate date

I am rather unfamiliar with regular expressions. I am trying to write a regular expression for mm.dd.yyyy, mm/dd/yyyy or mm-dd-yyyy. This is what I have so far, I am completely unsure if I am even close.

^[0-9]{4}-(((0[13578]|(10|12))-(0[1-9]|[1-2][0-9]|3[0-1]))|(02-(0[1-9]|[1-2][0-9]))|((0[469]|11)-(0[1-9]|[1-2][0-9]|30)))$

Thanks

Upvotes: 0

Views: 9071

Answers (6)

kennebec
kennebec

Reputation: 104780

I have seen some monster regular expressions to match actual dates- they would not match 04/31/yyyy, for instance, or 02-29-2011.

It is simpler to try to make a date from the input, and then check the input.

function isvalid_mdy(s){
    var day, A= s.split(/\D+/).map(function(itm){
        return parseInt(itm, 10)
    });
    try{
        day= new Date(A[2], A[0]-1, A[1]);
        if(day.getMonth()+1== A[0] && day.getDate()== A[1]) return day;
        throw 'Bad Date Format';
    }
    catch(er){
        return NaN;
    }

}

var s1= '04/31/2011';
isvalid_mdy(s1)

/*  returned value: (Number)
NaN

*/

Upvotes: 2

alex
alex

Reputation: 490253

/^\d{2}[.\/-]\d{2}[.\/-]\d{4}$/

jsFiddle.

Note that this will allow them to be mixed up, i.e. 01/02-2010 would be valid. To stop this, write it out three times like so...

/^(?:\d{2}\.\d{2}\.\d{4}|\d{2}\/\d{2}\/\d{4}|\d{2}-\d{2}-\d{4})$/

jsFiddle.

(or just check cwolves's wonderful answer.)


Your question title says...

Javascript Regular Expression to validate date

If you also need to extract the portions, wrap them with parenthesis (()) which will turn them into capturing groups. They will be stored in members of the returned array if a successful match.

Upvotes: 2

Dave Ward
Dave Ward

Reputation: 60580

An interesting trick is that you can use Date.parse() to do something along those lines:

// 1303617600000
Date.parse('4/24/2011')

// 1303617600000
Date.parse('4-24-2011')

// 1303617600000
Date.parse('4.24.2011')

// NaN
Date.parse('4/32/2011')

// NaN
Date.parse('foo')

It's not perfectly strict. For example, it will successfully parse 2/30/2011 as valid. It's a good 99%-strict sanity test though.

Upvotes: 0

manojlds
manojlds

Reputation: 301147

I don't like repeating the patterns once each for ., - and /

Try something like the below:

^(\d{2})(\/|-|\.)(\d{2})\2(\d{4})$

Note the use of \2 representing the second matching group which is the group of ., - or /. This will make sure that whatever symbol was between mm and dd will be matched between dd and yyyy.

Upvotes: 0

Rudie
Rudie

Reputation: 53831

In PHP I use named matches, so different formats are easy:

$format = 'y-m-d'; // or 'd-m-y' or 'd/m/y' etc
$regexp = '#^'.strtr(preg_quote($format), array('y' => '(?P<year>(?:1|2)\d{3})', 'm' => '(?P<month>\d\d?)', 'd' => '(?P<day>\d\d?)')).'$#';

but I don't think it's possible like that in JS. Maybe named matches some other way...

edit
I tried this:

'2004-8-29'.match(/^(\3\d{4})-(\2\d\d?)-(\1\d\d?)$/)

but I don't think that's it... (Notice the \3, \2 and \1 before the actual captures/matches)

In order 1, 2, 3, it matches. In order 3, 2, 1, it doesn't. Not sure what the \1, \2 and \3 do =)

Upvotes: 0

user578895
user578895

Reputation:

/^\d{2}([.\/-])\d{2}\1\d{4}$/

will match 01/01/2000, 01.01.2000, NOT 01/01.2000

/^(\d{2})([.\/-])(\d{2})\2(\d{4})$/

does the same while wrapping the three date parts.

Upvotes: 2

Related Questions