achristoph
achristoph

Reputation: 125

How to make US date format as the default when saving to a model in Rails 3

The US date used to be accepted/parsed correctly, but not anymore in Rails 3. The %Y-%m-%d is accepted but not %m/%d/%Y.

g = Grant.new
g.budget_begin_date = '12/31/2010'
#g.budget_begin_date returns nil
g.budget_begin_date = '2010-12-31'
#g.budget_begin_date returns Fri, 31 Dec 2010 00:00:00 UTC +00:00

Upvotes: 7

Views: 1352

Answers (5)

smathy
smathy

Reputation: 27961

In modern ruby (ie. with prepend) you can insert your own type casting in front of Rails's. You'll want to do this for whatever other date/time formats you're using. Here's the code for Date, just stick this in an config/initializers/typecasts.rb or somewhere:

module Typecasting
  module Date
    def cast_value v
      ::Date.strptime v, "%m/%d/%Y" rescue super
    end  
  end  

  ::ActiveRecord::Type::Date.prepend Date
end

Rails will try the American format and fall back to using the builtin method if that didn't work.

Upvotes: 0

Tom Harrison
Tom Harrison

Reputation: 14028

As of Ruby 1.9, Date.parse stopped handling the ambiguous format mm/dd/yyyy (american format) or dd/mm/yyyy (rest of civilized world format).

The american_date gem linked here makes the assumption older Ruby did, and can thus parse an american date as expected.

Upvotes: 4

dgmdan
dgmdan

Reputation: 415

Your code example doesn't quite show Date.parse failing to interpret US style dates, but you're right, it doesn't. Instead of this:

Date.parse("12/31/2010")

Use this:

Date.strptime("12/31/2010", "%m/%d/%Y")

Upvotes: 4

Prasad Surase
Prasad Surase

Reputation: 6574

The Date class calls self.parse method to parse the provided string to date.

1.9.2p320 :051 > x = Date.parse('2011-31-12')
ArgumentError: invalid date
from .../rubies/ruby-1.9.2-p320/lib/ruby/1.9.1/date.rb:1022:in `new_by_frags'
from .../rubies/ruby-1.9.2-p320/lib/ruby/1.9.1/date.rb:1066:in `parse'

which is turn calls a self method "_parse" which is located in the file ".../ruby-1.9.2-p320/lib/ruby/1.9.1/date/format.rb".

it calls the strftime function("def strftime(fmt='%F')") where the default format for date formating is "%F" which according to the Time class documentation is " %F - The ISO 8601 date format (%Y-%m-%d)".

Upvotes: 0

hwrd
hwrd

Reputation: 2180

If you are not averse to using a gem, you can check out the Chronic gem: https://github.com/mojombo/chronic

You can have Chronic parse your begin date before saving the model.

Upvotes: 1

Related Questions