How to convert a localized string date to Ruby Date object?

1.7k views Asked by At

I have a date which works fine when using it as English

> Date.strptime("Aug 02, 2015", "%b %d, %Y")
Sun, 02 Aug 2015

However when I use it another language es, that doesnt work. E.g.

> Date.strptime("ago 02, 2015", "%b %d, %Y")
ArgumentError: invalid date

The text strings ago 02, 2015 itself comes from another service, and I need to standardize it to a particular format such as

> I18n.localize(Date.strptime("Aug 02, 2015", "%b %d, %Y"), format:  "%m/%d/%Y")
"08/02/2015"

Is there a way to do this in Ruby, so that

> I18n.localize(Date.strptime("ago 02, 2015", "%b %d, %Y"), format:  "%m/%d/%Y")
"08/02/2015"
2

There are 2 answers

3
chris-tulip On

I'm assuming you've already tried the following function which handles most scenarios for turning something into a DateTime object.

@date = Date.parse("ago 02, 2015") 

Other than that you can try appending to the date constants so that it properly picks them up. Personally haven't tried this approach but might work for you?

require 'date'
Date::MONTHNAMES      = [nil] + %w( Enero Febrero Marzo Abril Mayo Junio Julio Agosto Septiembre Octubre Noviembre Diciembre )
Date::DAYNAMES        = %w( Lunes Martes Miércoles Jueves Viernes Sábado Domingo )
Date::ABBR_MONTHNAMES = [nil] + %w( Ene Feb Mar Abr May Jun Jul Ago Sep Oct Nov Dic )
Date::ABBR_DAYNAMES   = %w( Lun Mar Mié Jue Vie Sáb Dom )

Lastly, have you considered using the Chronic Gem for date parsing? I believe it should handle cross language cases.

1
EJAg On

You can substitute the Spanish words with English first. You can do it with #gsub, I18n yaml lookup, or a dictionary method, e.g.

dictionary = { "ago" => "Aug" }
date = "ago 02, 2015"
words = date.split
words[0] = dictionary[words[0]]
date = words.join(" ")  # "Aug 02, 2015"

Refactor it to take advantage of the power of OOP:

class DateDictionary 
  LOOKUP = { "ene" => "Jan", "ago" => "Aug" }

  def translate(date)
    words = date.split
    words[0] = LOOKUP[words[0]]
    date = words.join(" ")
  end
end

date = DateDictionary.new.translate("ago 02, 2015")  #  "Aug 02, 2015"