Note that there are some explanatory texts on larger screens.

plurals
  1. POHow can I use US-style dates in Rails using Ruby 1.9?
    primarykey
    data
    text
    <p>I'm in the U.S., and we usually format dates as "month/day/year". I'm trying to make sure that my Rails app, using Ruby 1.9, assumes this format everywhere, and works the way it did under Ruby 1.8.</p> <p>I know that lots of people have this issue, so I'd like to create a definitive guide here.</p> <p>Specifically:</p> <ol> <li>'04/01/2011' is April 1, 2011, not Jan 4, 2011.</li> <li>'4/1/2011' is also April 1, 2011 - the leading zeros should not be necessary.</li> </ol> <p><strong>How can I do this?</strong></p> <p>Here's what I have so far.</p> <h2>Controlling Date#to_s behavior</h2> <p>I have this line in <code>application.rb</code>:</p> <pre><code> # Format our dates like "12/25/2011' Date::DATE_FORMATS[:default] = '%m/%d/%Y' </code></pre> <p>This ensures that if I do the following:</p> <pre><code>d = Date.new(2011,4,1) d.to_s </code></pre> <p>... I get "04/01/2011", not "2011-04-01".</p> <h2>Controlling String#to_date behavior</h2> <p>ActiveSupport's <code>String#to_date</code> method currently looks like this (<a href="https://github.com/lifo/docrails/blob/9d97173c5a3f023e50f85503c120fbad9d0b26d2/activesupport/lib/active_support/core_ext/string/conversions.rb">source</a>):</p> <pre><code> def to_date return nil if self.blank? ::Date.new(*::Date._parse(self, false).values_at(:year, :mon, :mday)) end </code></pre> <p>(In case you don't follow that, the second line creates a new date, passing in year, month and day, in that order. The way it gets the year, month and day values is by using <code>Date._parse</code>, which parses a string and somehow decides what those values are, then returns a hash. <code>.values_at</code> pulls the values out of that hash in the order <code>Date.new</code> wants them.)</p> <p>Since I know that I will normally pass in strings like "04/01/2011" or "4/1/2011", I can fix this by monkeypatching it like this:</p> <pre><code>class String # Keep a pointer to ActiveSupport's String#to_date alias_method :old_to_date, :to_date # Redefine it as follows def to_date return nil if self.blank? begin # Start by assuming the values are in this order, separated by / month, day, year = self.split('/').map(&amp;:to_i) ::Date.new(year, month, day) rescue # If this fails - like for "April 4, 2011" - fall back to original behavior begin old_to_date rescue NoMethodError =&gt; e # Stupid, unhelpful error from the bowels of Ruby date-parsing code if e.message == "undefined method `&lt;' for nil:NilClass" raise InvalidDateError.new("#{self} is not a valid date") else raise e end end end end end class InvalidDateError &lt; StandardError; end; </code></pre> <p>This solution makes my tests pass, but is it crazy? Am I just missing a configuration option somewhere, or is there some other, easier solution?</p> <p>Are there any other date-parsing cases I'm not covering?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload