How to convert a localized string date to Ruby Date object?
Asked Answered
T

2

6

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"
Thaliathalidomide answered 7/9, 2017 at 21:35 Comment(1)
are you looking for a fully language agnostic solution so it works for all or just for English?Suisse
S
1

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.

Suisse answered 7/9, 2017 at 23:36 Comment(3)
Tried Chronic, but it doesn't support i18n, either since it uses the ruby Time class.Thaliathalidomide
Have you tried either of the other options I suggested?Suisse
Date.parse doesnt take non English month names. The other didn't work either (atleast on Rails console), and ofcourse its overriding constants - bad practiceThaliathalidomide
F
0

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"
Forgetful answered 7/9, 2017 at 23:22 Comment(1)
Not ideal, but this is nearly what I went with except no need for a dictionary itself. Since this is rails used the locale keys for months namesThaliathalidomide

© 2022 - 2024 — McMap. All rights reserved.