views:

485

answers:

4

I've got a batch of a 100k or so records that I'm importing to a Rails app.

There's a date in each row formatted like the following: 03/17/81

However, when I try to just assign it to a date field, it gets converted as follows:

ruby-1.8.7-p174 > "03/17/81".to_date
 => Sat, 17 Mar 0081 

Ultimately I would like the format to result in 1981-03-17

Would this best be done on the import or should I be overriding in my Rails config to set the date standard to the format I need and what's the right approach in Rails 2.3.5?

A: 

Try Chronic (gem install chronic):

require 'rubygems'
require 'chronic'
puts Chronic.parse "03/17/81"
#=> Tue Mar 17 12:00:00 -0800 1981

Returns a Time object.

Ben
Why should you install a Gem to perform a simple operation you can perform with a few lines of code?
Simone Carletti
Because once it's installed, it's only 2 lines. And it's *very* flexible.
Ben
A: 

Don't change Rails, change your code. I don't see any problem in creating a method that converts the string into a suitable date.

string = "03/17/81"
date   = if string =~ %r{(\d+)/(\d+)/(\d+)}
  Date.parse("19#{$3}-#{$1}-#{$2}")
else
  nil # failover
end
Simone Carletti
that was my first thought too :)
Niklaos
We're a decade into the 2000s.
Ben
@ BenIndeed, the code might need some changes. The question didn't set any requirement about 20xx dates.
Simone Carletti
So, why not use a library (gem) that has been written and tested to parse this and other formats? No need to reinvent wheels, etc.
Ben
This is not reinventing the weel, it's using 3 lines of code instead of importing a bunch of not-needed-generic-features into your execution stack.
Simone Carletti
+4  A: 

Use

d = Date.strptime("03/17/81", "%m/%d/%y")

To get it out in 1981-03-17 use:

d.to_s

See Date Rubydoc.

TheClair
Doest work result : 0081-03-17
Niklaos
Note that for dates before 1969, this will result in the incorrect century: `Date.strptime("12/31/68", "%m/%d/%y")` results in December 31, 2068.
Greg Campbell
Did you require 'date' in irb? Plus the %y is case sensitive, it has to be lower case, upper case means a 4 digit year.
TheClair
Greg is completely correct. Depending on your data you may have to manually adjust those dates. The '-' operator will work with Date objects, so you can just subtract 100 years (if needed).
TheClair
@TheClair : My mistake, my Y was in caps ! thanks :)
Niklaos
Ran against a few thousand records in my import and it seems to have handled all of the dates as expected. No dates prior to 1969 so I think I'm in the clear in that regard. Thanks for the quick snippet; I knew it would be trivial.
mwilliams
*blink* How did I never know about strptime?
wesgarrison
A: 

The proper way to do this, if you are going to reuse the format in multiple places is to do something like this: http://seanbehan.com/ruby-on-rails/custom-date-formats-for-your-rails-application/

Create a file config/initializers/date_formats.rb

...containing this:

ActiveSupport::CoreExtensions::Date::Conversions::DATE_FORMATS.merge!(
  :short_date => "%Y/%m/%d"
)

Then you should see:

ruby-1.8.7-p174 > date = "03/17/81".to_date
ruby-1.8.7-p174 > date.to_s(:short_date)
#=> "1981/03/17"
Midwire