Reputation: 295
I'm trying to write some regular expressions to validate MM/DD/YYYY date entry. Each part of the date is a separate input textfield separated by a "/" like:
01 / 16 / 1985
For a date of January 16, 1985.
I have it now where it only allows numeric entries, which was easy using replace() and a simple regex. BTW, regex's are not my forte, I don't do much of them, maybe once or twice every couple years.
Below is the code I'm using as well as some psuedo-regex underneath my replace(). I'm having a hard time tying the numeric entry regex in with the date formatting regex I'm trying to achieve (commented out under replace())
//MM
$(this).keyup(function() {
//allow only numbers
this.value = this.value.replace(/[^0-9]/g, '');
//(0[1-9]|1[012])
//matching 01 (Jan) to 09 (Sep) to 10 (Oct) to 12 (Dec)
});
//DD
$(this).keyup(function() {
//allow only numbers
this.value = this.value.replace(/[^0-9]/g, '');
//(0[1-9]|[12][0-9]|3[01])
//matching 01-09, 10-19, 20-29, 30-31
//(not worried about picking 31 in February)
});
//YYYY
$(this).keyup(function() {
//allow only numbers
this.value = this.value.replace(/[^0-9]/g, '');
//(\d{4})
//really simple 4 digit, but don't really want 1245 as a valid year
//a range from 1900-current year would be great
//( 1900-newDate().getFullYear() )
//something like this possible?
);
Upvotes: 1
Views: 4590
Reputation: 555
(?:0[1-9]|1[0-2])/(?:0[1-9]|[12][0-9]|3[01])/(?:19|20)[0-9]{2}
(?:text)
prevents the backreference, remove the ?:
if you would need it/
--> \/
Three different fields is just a matter of splitting up, the /
being the delimiter.
Day (01 to 31)
0[1-9]|[12][0-9]|3[01]
Month (01 to 12)
0[1-9]|1[0-2]
Year (1900-2099)
(?:19|20)[0-9]{2}
Upvotes: 4
Reputation: 91385
You'd better do a split on / and test all individual parts. But if you really want to use a regex you can try this one :
#^(?:(?:(?:(?:0?[13578])|(1[02]))/31/(19|20)?\d\d)|(?:(?:(?:0?[13-9])|(?:1[0-2]))/(?:29|30)/(?:19|20)?\d\d)|(?:0?2/29/(?:19|20)(?:(?:[02468][048])|(?:[13579][26])))|(?:(?:(?:0?[1-9])|(?:1[0-2]))/(?:(?:0?[1-9])|(?:1\d)|(?:2[0-8]))/(?:19|20)?\d\d))$#
Explanation:
^ # start of line
(?: # group without capture
# that match 31st of month 1,3,5,7,8,10,12
(?: # group without capture
(?: # group without capture
(?: # group without capture
0? # number 0 optionnal
[13578] # one digit either 1,3,5,7 or 8
) # end group
| # alternative
(1[02]) # 1 followed by 0,1 or 2
) # end group
/ # dash
31 # number 31
/ # dash
(19|20)? #numbers 19 or 20 optionnal
\d\d # 2 digits from 00 to 99
) # end group
|
(?:(?:(?:0?[13-9])|(?:1[0-2]))/(?:29|30)/(?:19|20)?\d\d)
|
(?:0?2/29/(?:19|20)(?:(?:[02468][048])|(?:[13579][26])))
|
(?:(?:(?:0?[1-9])|(?:1[0-2]))/(?:(?:0?[1-9])|(?:1\d)|(?:2[0-8]))/(?:19|20)?\d\d)
)
$
I've explained the first part, leaving the rest as an exercise.
This match one invalid date : 02/29/1900 but is correct for any other dates between 01/01/1900 and 12/31/2099
Upvotes: 1
Reputation: 11765
the regular expression for the date format that you want should be something like this
[0-9]{2}/[0-9]{2}/[0-9]{4}
this should work.
Upvotes: 0