Reputation: 5178
On rubular I tested and confirmed that this does a good job confirming the desired format of a date entry:
\A\d\d\/\d\d\/\d\d\d\d\z
Tests:
01/02/2000 #pass
11/21/2014 #pass
11-21-2014 #fail
A3-21-2014 #fail
I want to make it a little bit better, and it will be good enough for me. What I want is to confirm that the "month field" (the first two digits) is anywhere from 01 - 12, where each single digit is led by a zero. (Ex: 01,02,03 etc as opposed to: 1,2,3).
Next: I want to do the same thing for the next two digits to confirm that the next two digits (the day field) is between 01 - 31. Same thing: Each single digit needs to lead with a zero.
Tests:
01/02/2017 #pass
12/31/2017 #pass
1/02/2017 #fail
01/2/2017 #fail
50/01/2017 #fail
01/50/2017 #fail
I realize that this regex will be inaccurate for those months that have fewer than 31 days, but it is good enough for what I am doing.
Upvotes: 0
Views: 1576
Reputation: 5178
What I did was used the american_date gem. On your date inputs: the user should enter the date in the format of: "mm/dd/yyyy".
In order to force the user to enter the date in this format: I used jquery-inputmask-rails. I defined my mask like so:
$('.mask_american_date').inputmask({mask: "99/99/9999"});
Now there will be a nice mask on the date input that looks like this:
__/__/____
Now: all you need is a presence validator for the date field in your model:
validates_presence_of :date_of_birth, message: "Date is either invalid or is not present".
And this covers everything. How american date works is it takes the user input and attempts to convert it into a date. If it cannot convert the user input into a date for any reason: it will return nil
which triggers the above validation.
nil
.Upvotes: 1
Reputation: 29328
Well this should get you most of the way there:
/((02\/[0-2]\d)|((01|[0][3-9]|[1][0-2])\/(31|30|[0-2]\d)))\/[12]\d{3}/
Granted it does not handle the following:
Small Breakdown in case links break:
Here is the runout on Rubular Here is an explanation from Regex101
(02\/[0-2]\d)
- Starts with 02/ then allow 0-2 followed by 0-9((01|[0][3-9]|[1][0-2]\/(31|30|[0-2]\d))
- Starts with (01 or 0 followed by 3-9 or 1 followed by 0-2) followed a / followed by 31 or 30 or 0-2 followed by 0-9Really wish ruby supported look behind conditionals like true pcre Example for edification
As a Note: as mentioned in the comments rescuing a parsing failure is probably easier than using a regex but I figured since you asked.
Upvotes: 1