views:

871

answers:

6

My simple date validation regex is not working correctly...

validates_format_of :dob, :with => /\d{2}\/\d{2}\/\d{4}/, :message => "^Date must be in the following format: mm/dd/yyyy"

What am I missing here? I'm trying to validate that a date is in the following format: mm/dd/yyyy - When I enter what should be valid data, I still get the error message.

Thanks for the help so far. Here's a snippet of code from my form that is passing the dob value in:

    <tr>        
      <td>
        <%= f.label :dob, "Date of Birth:  " %>
      </td>
      <td>
        <%= calendar_date_select_tag "user[dob]", "", :format => :american, :year_range => 50.years.ago..0.years.ago %>
      </td>
    </tr>

I think it may have something to do with my use of this js calendar plugin. A related problem is that my dob value is not maintained in the field if the post fails validation - the previously entered date value clears out...

Thanks!

Tom

+3  A: 

I've not tested your code within a Rails app, but your regular expression looks good to me. Try this test program:

#!/usr/bin/ruby

str   = '08/24/2009'
regex = /\d{2}\/\d{2}\/\d{4}/

if str =~ regex
   print 'matched', "\n"
else
   print 'did not match', "\n"
end

Your regular expression matches. That suggests the problem is elsewhere.

You also might think about trying more general solutions for parsing a date in Ruby, such as the Date.parse method of the Date class. This does a little bit more validation than your regular expression, and it also provides some useful methods for converting dates between different formats.

James Thompson
+1  A: 

The regex looks correct to me. A useful resource is http://www.rubyxp.com/, which will test your regular expression against a given string. Indeed, the regex you have matches a date I typed into rubyxp.

Perhaps there's an issue in getting the entered data -- any chance the field is really called da?

Another item you may find useful: validates_timeliness, a rails plugin to validate dates and times. Why just validate the date format when you can check if it's a real date -- after all, 99/99/9999 will validate against your regex, but you may not really want to accept that.

JacobM
A: 

You might also want to look into the Chronic Gem (http://chronic.rubyforge.org/) which does natural date parsing. So you can enter in :

Next tuesday at 9pm

And it will interpret it correctly.

jonnii
+2  A: 

You are probably using a string field to store a date. Consequently, any helpers that expect a DateTime or Time value will not work properly. You will need to investigate multiparameter assignments in Rails to figure out the proper way to do what you want to do (multiparemeter assignments is the magic behind sending 4 fields to Rails and get them converted to a DateTime or Time object).

In other words: if you are using a true DateTime field (as you should for this case) the validates_format_of will not have any effect (or will have adverse effects)

Julik
+1 Definitely sounds like something I should look into - thanks!
cakeforcerberus
+1  A: 

Ahhh! Forcing date formats on the end-user when Rails implicitly converts them is a bad thing for usability, along with being more work for you (as you've seen).

If you've got a date/time attribute in your model, Rails will do its best to convert via Date.Parse (http://www.ruby-doc.org/core/classes/Date.html#M000644), e.g.

u = Somemodel.find :first

u.created_at
=> Tue Nov 20 15:44:18 -0500 2007

u.created_at = '2008/07/03'
=> "2008/07/03"

u.created_at
=> Thu Jul 03 00:00:00 -0400 2008

u.created_at = '05/10/1980'
=> "05/10/1980"

u.created_at
=> Sat May 10 00:00:00 -0400 1980
Matt Rogish
You're certainly right. I didn't realize that Rails did some magic in the background to parse the user's input (a side effect of programming in C# for my day job I guess :)) - I'm pretty sure I am storing it as a string at the moment, so I'll just switch it over to a date and remove the validates_format_of. Thanks :) +1
cakeforcerberus
A: 

Found an excellent gem / plugin for all your date / time validations.

validates_timeliness

http://github.com/adzap/validates_timeliness/issues

Dom