Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I parse non-English dates with DateTime strptime in Ruby?

I am trying to parse dates exported from a CMS. Unfortunately with a Swedish locale set. The month names are abbreviated to three characters which makes a difference when it comes to the months May and October ("maj" vs. "May", and, "okt" vs. "Oct").

I would expect to use DateTime.strptime with correct locale set to solve this issue, like this:

require 'locale'
Locale.default = "sv_SE"
require 'date'
DateTime.strptime("10 okt 2009 04:32",'%d %b %Y %H:%M')

The date is however still parsed as it would be using abbreviated month names in English:

ArgumentError: invalid date
    from lib/ruby/1.9.1/date.rb:1691:in `new_by_frags'
    from lib/ruby/1.9.1/date.rb:1716:in `strptime'
    from (irb):9
    from bin/irb:16:in `<main>'

Question 4339399 touches on the same subject and links to a complex solution for fixing this.

Is there a more elegant solution to this? Is this even considered a bug in Ruby?

like image 219
moonhouse Avatar asked Sep 28 '11 08:09

moonhouse


1 Answers

To be honest, since you only have two months that are different, I'd probably just gsub them:

DateTime.strptime("10 okt 2009 04:32".gsub(/okt/,'Oct'),'%d %b %Y %H:%M')

If you want you can put that into a small helper:

def swedish_to_english_date(date_string)
  date_string.gsub(/may|okt/, 'may' => 'May', 'okt' => 'Oct')
end

DateTime.strptime(swedish_to_english_date("10 okt 2009 04:32"),'%d %b %Y %H:%M')
#=> #<DateTime: 110480161/45,0,2299161>

Edit: Note that the gsub with a hash as the second argument is a 1.9 thing, in 1.8 you can do something like

>> months = { 'may' => 'May', 'okt' => 'Oct' }
=> {"okt"=>"Oct", "may"=>"May"}
>> "may okt".gsub(/may|okt/) { |match| months[match] }
=> "May Oct"
like image 118
Michael Kohl Avatar answered Sep 30 '22 01:09

Michael Kohl