title: How to validate a date string in Rails
body: <p>OK, so there's a bunch of answers on related topics, but for some reason it seems that no one is interested in the following very-real problem:</p>
  
  <p>I have a <code>Timecard</code> model, with <code>to_date</code> and <code>from_date</code> fields. I'm using <code>jquery.ui.datepicker</code> and generally speaking - all is well. I'm also using the 'validates_timeliness' gem:</p>
  
  <pre><code>class Timecard &lt; ActiveRecord::Base
    ...
    validates_date :to_date
    validates_date :from_date
    ...
  end
  </code></pre>
  
  <p>However, if the user decides to manually edit the text field, entering something like '29-Feb-2013' (which is an invalid date), this date will be converted to '01-Mar-2013'. The following spec will fail:</p>
  
  <pre><code>describe "POST #create" do
    ...
    context "with invalid attributes (invalid date)" do
      it "re-renders the :new template" do
        timecard = fix_date_attribs_for(:timecard_feb)
         # Manually create an invalid date in the params hash - Feb only has 28 days
        timecard['to_date(3i)'] = 29
        post :create, timecard: timecard
        response.should render_template :new
      end
    end
    ...
  end
  </code></pre>
  
  <p>The following <code>puts</code> in <strong>timecards_controller.rb</strong>:</p>
  
  <pre><code>def create
    @timecard = Timecard.new(timecard_params)
    puts "&gt;&gt;&gt;&gt; #{@timecard.valid?} - #{@timecard.to_yaml}"
    ...
  end
  </code></pre>
  
  <p>yields the following output when running the above spec:</p>
  
  <pre><code>.&gt;&gt;&gt;&gt; true - --- !ruby/object:Timecard
  attributes:
    id: 
    name: February 2013
    from_date: 2013-02-01
    to_date: 2013-03-01
    created_at: 
    updated_at: 
  F
  
  Failures:
  
    1) TimecardsController POST #create with invalid attributes (invalid date) re-renders the :new template
       Failure/Error: response.should render_template :new
         expecting &lt;"new"&gt; but rendering with &lt;[]&gt;
       # ./spec/controllers/timecards_controller_spec.rb:65:in `block (4 levels) in &lt;top (required)&gt;'
  
  Finished in 0.28495 seconds
  17 examples, 1 failure
  </code></pre>
  
  <p>How do I do input validation here? Using callbacks in the model seem too far off (since the problem occurs before - when the controller does <code>@timecard = Timecard.new(timecard_params)</code>). I could try to catch a <code>Date.new(relevant_timecard_params)</code> exception in the controller, but it doesn't have access to the <code>errors</code> hash so I wouldn't be able to tell the user it's an invalid date, not to mention that the controller doesn't sound like the right place to do input validation... Please help...</p>
  
  <h1>Update 1</h1>
  
  <p>With 'validate_timeliness' as @Grantovich suggested below (with the plugin enabled) and <code>save</code> and <code>update</code> fail with invalid dates such as '29-Feb-2013' even without writing <code>validates_date :to_date</code> in the model. When adding <code>validates_date</code>, <code>save</code> and <code>update</code> fail and the validated fields are set to <code>nil</code> even on perfectly valid input (by the validation logic, I suspect).</p>
  
  <p>Also tried specifying the format: <code>validates_date :to_date, format: 'dd-mmm-yyyy'</code> but got the same results.</p>