I recently ran into an interesting issue while working on a Rails 3, Ruby 1.9.3 project.
My needs were simple: I had a single text field that allowed the user to enter a date in MM/DD/YYYY format. It was also bound to the jquery calendar plugin which was configured to prefill the textbox with the selected date in MM/DD/YYYY format. However, every time a new record was created, this date would be written as null.
When I forced the date to be YYYY/MM/DD format, it would save the date just fine. However, I didn't feel this date was as human readable. I also didn't want to continually wrestle with the jquery calendar altField, altFormat options just to work around the problem.
If you also are fighting this issue, you can skip to the end to fix it. It's fine, I won't be offended.
Given that I have a Person:
ActiveRecord::Schema.define(:version => 20120218015632) do create_table "people", :force => true do |t| t.string "name" t.date "birthdate" t.datetime "created_at" t.datetime "updated_at" end end
And an empty ActiveRecord model:
class Person < ActiveRecord::Base end
You find that you cannot even set the birthdate in MM/DD/YYYY format:
p = Person.create p.birthdate = "04/29/2000" => "04/29/2000" p.birthdate => nil #oh, noes! p.birthdate = "2000-04-29" => "2000-04-29" p.birthdate => "Sat, 29 Apr 2000" #oh, my!
The problem here is how Ruby 1.9 now handles Date parsing.
Mats himself directly addresses this change:
"dd/dd/dd" format itself is very culture dependent and ambiguous. It is yy/mm/dd in Japan (and other countries), mm/dd/yy in USA, dd/mm/yy in European countries, right? In some cases, you can tell them by accident, but we should not rely on luck in general cases. I believe that is the reason parsing this format is disabled in 1.9.
And just to solidify this problem:
irb: Date.parse('04/29/2000') ArgumentError: invalid date from /Users/aaronchristy/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/date.rb:1022:in `new_by_frags' from /Users/aaronchristy/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/date.rb:1066:in `parse' from (irb):1 from /Users/aaronchristy/.rvm/rubies/ruby-1.9.2-p290/bin/irb:16:in `' irb: Date.parse('2000/04/29') ===> Date: 2000-04-29 (4903327/2,0,2299161)
The solution for this problem is to correctly translate MM/DD/YYYY into proper ISO format YYYY-MM-DD.
Luckily, this work has already been done for you and wrapped up in the american-date gem.
~ gem install american_date Fetching: american_date-1.0.0.gem (100%) Successfully installed american_date-1.0.0 irb: Date.parse('04/29/2000') ArgumentError: invalid date from /Users/aaronchristy/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/date.rb:1022:in `new_by_frags' from /Users/aaronchristy/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/date.rb:1066:in `parse' from (irb):1 from /Users/aaronchristy/.rvm/rubies/ruby-1.9.2-p290/bin/irb:16:in `' irb: require 'american_date' ===> true irb: Date.parse('04/29/2000') ===> #Date: 2000-04-29 (4903327/2,0,2299161)
Now get back to doing something useful.