Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Localizing datetimes in Rails I18n

In my locale rails console, I can see that I have the following locales available via the I18n gem

> I18n.available_locales
=> [:en, :de, :es, :ja, :"pt-BR", :"zh-CN", :"zh-HK", :"zh-TW"]

I try using localize with a specific date format in English -

> I18n.with_locale("en") { I18n.l(Time.zone.now, format: "%B, %Y") }
=> "April, 2016"

Which works great. Then I try the same thing with Spanish and Japanese -

> I18n.with_locale("es") { I18n.l(Time.zone.now, format: "%B, %Y") }
=> "s, 2016"
> I18n.with_locale("ja") { I18n.l(Time.zone.now, format: "%B, %Y") }
=> "s, 2016"

It looks like the month name is being translated as "s".

The rails I18n gem definitely defines month names for the above locales. Does the #localize method even make use of those, or is it trying to pull from elsewhere?

Thanks!

like image 378
user2490003 Avatar asked Apr 27 '16 05:04

user2490003


2 Answers

I received the same set of outputs as you have mentioned.The following are the steps I followed to debug the behaviour.

  1. Checked if rails-i18n is part of my rails application by checking the Gemfile.lock (Actually, it is not). The I18n gem that is part of my Gemfile.lock is a dependency from activesupport gem

  2. Checked I18n load path for any translations file for "es" locale I18n.load_path. There were none.

  3. Went through the I18n.translate method for how it handles date and time formats. The format directives [%a, %A, %b, %B, %p, %P] in the format string are only used for localization (day, month, meridian (AM/PM) indicator - both shorter and longer formats) since only those contain language texts.

I18n.with_locale(:en) { I18n.localize(Time.zone.now, format: "%B, %Y") }

internally calls

I18n.translate(:"date.month_names", :locale => :en)[Time.zone.now.mon]

that returns "April"

Similarly,

I18n.with_locale(:es) { I18n.localize(Time.zone.now, format: "%B, %Y") }

internally calls

I18n.translate(:"date.month_names", :locale => :es)[Time.zone.now.mon]

But there are no translations available,

I18n.translate(:"date.month_names", :locale => :es)

=> "translation missing: es.date.month_names"

Time.zone.now.mon = 4.So, it returns "translation missing: es.date.month_names"[4] which is "s"

Hope this helps.

like image 106
Aravind.S Avatar answered Oct 17 '22 18:10

Aravind.S


I was facing the same issue, i used I18n for localizing my rails application for spanish. while doing time translation it was working fine for english as follows:

   I18n.l(raw_date.to_time, format: :long) = "Tuesday, July 11, 2017" 

For Spanish i was getting

  I18n.l(raw_date.to_time, format: :long) = "a, t 11, 2017" 

I updated my es.yml document with date, day_name, month_name, abbr_day_names, abbr_month_names as follows:

es:
 date:
   day_names:
    - domingo
    - lunes
    - martes
    - miércoles
    - jueves
    - viernes
    - sábado
   month_names:
   -
   - enero
   - febrero
   - marzo
   - abril
   - mayo
   - junio
   - julio
   - agosto
   - septiembre
   - octubre
   - noviembre
   - diciembre
 time:
  formats:
   long: '%A, %B %d, %Y'
   short: '%b %d, %Y'

After that for spanish i got the desired result.

I18n.l(raw_date.to_time, format: :long) = "viernes, julio 21, 2017"

on going through documents i found out that by default I18n will include date, day_name, month_name, abbr_day_names, abbr_month_names for english, where as for spanish and other languages of interest we need to add these fields in the respective yaml documents that we are maintaining. This is the link to get these fields for respective languages.

like image 3
kgangadhar Avatar answered Oct 17 '22 19:10

kgangadhar