Validating date formats in rails

22,873

Solution 1

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.

Solution 2

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)

Solution 3

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

validates_timeliness

http://github.com/adzap/validates_timeliness

Solution 4

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

Solution 5

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.

Share:
22,873
cakeforcerberus
Author by

cakeforcerberus

x

Updated on August 16, 2020

Comments

  • cakeforcerberus
    cakeforcerberus over 3 years

    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

  • cakeforcerberus
    cakeforcerberus over 14 years
    +1 Definitely sounds like something I should look into - thanks!
  • cakeforcerberus
    cakeforcerberus over 14 years
    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
  • Mohamad
    Mohamad about 11 years
    @Matt Rogish what if you just want to validate that the string is a date without regard to the date format?
  • Matt
    Matt over 10 years
    Your link is broken for Date.parse. Here is a new link to a parse function for the date class, but it specifically states its function is not to validate format.