Rails 2.3.5 I18n month/day name translation problem - ruby-on-rails

My config/locales/pl.yml file (sampled from here):
pl:
date:
day_names: [Niedziela, Poniedziałek, Wtorek, Środa, Czwartek, Piątek, Sobota]
month_names: [~, Styczeń, Luty, Marzec, Kwiecień, Maj, Czerwiec, Lipiec, Sierpień, Wrzesień, Październik, Listopad, Grudzień]
In script/console:
I18n.locale = 'pl'
=> "pl"
Time.now.strftime("%A, %B")
=> "Tuesday, August"
Why? Or put it another way - how can I get translated month names? I'll also note that the locale file is definitely read as it includes a bunch of other translations, which all work.

That depends on which rails version you are using.
There's a helper to translate that, on rails 3.0.0 (I don't know from which version it was made available).
In a view, you can write
localize Time.now, :format => '%A, %B'
in script/console (or rails console), try typing:
controller.localize Time.now, :format => '%A, %B'
and see if it works.
There's also the lhelper (lowercase L), which is a shorthand for localize:
controller.l Time.now, :format => '%A, %B'

Related

rails localization of date format gives unexpected results [duplicate]

I've got a strange problem with date translations in my Ruby On Rails 3 application, and I really don't understand why...
Here are my en.yml and fr.yml :
fr:
date:
formats:
default: "%d/%m/%Y"
short: "%e %b"
long: "%e %B %Y"
time:
formats:
default: "%d %B %Y %H:%M:%S"
short: "%d %b %H:%M"
long: "%A %d %B %Y %H:%M"
am: 'am'
pm: 'pm'
en:
date:
formats:
default: "%Y-%m-%d"
long: "%B %d, %Y"
short: "%b %d"
time:
am: am
formats:
default: ! '%a, %d %b %Y %H:%M:%S %z'
long: ! '%B %d, %Y %H:%M'
short: ! '%d %b %H:%M'
pm: pm
This is not specific to a particuliar view, but for instance in one of my view :
<td><%=l job_application.created_at, :format => :default %></td>
I get those strange outputs :
With locale = :en
=> t, 30 o 2012 18:09:33 +0000
With locale = :fr
=> 30 o 2012 18:09:33
Where do these wrong "formats" come from ?
I'm using Rails 3.2.8 (with Postgresql / gem pg), and everything related to I18n works fine except for dates.
Thanks for any help !
I think I've finally figured this out, sorry for taking so long.
The Rails l helper just calls I18n.localize. If you trace through the I18n.localize code, you'll end up here:
format = format.to_s.gsub(/%[aAbBp]/) do |match|
case match
when '%a' then I18n.t(:"date.abbr_day_names", :locale => locale, :format => format)[object.wday]
when '%A' then I18n.t(:"date.day_names", :locale => locale, :format => format)[object.wday]
when '%b' then I18n.t(:"date.abbr_month_names", :locale => locale, :format => format)[object.mon]
when '%B' then I18n.t(:"date.month_names", :locale => locale, :format => format)[object.mon]
when '%p' then I18n.t(:"time.#{object.hour < 12 ? :am : :pm}", :locale => locale, :format => format) if object.respond_to? :hour
end
end
So the localize helper doesn't use strftime for the "stringy" parts of the date/time, it tries to do it by itself. Add the translations (as arrays in your YAML) for the month and day names as above and your localized dates and times should start working.
If you don't have those translation arrays in your YAML, then I18n.t(:"date.abbr_month_names") will give you strings like this:
"translation missing: en.date.abbr_month_names"
and then I18n.localize will end up doing silly things like this:
"translation missing: en.date.abbr_month_names"[10]
That will use String#[] instead of the expected Array#[] and you end up with random looking single character month and day names.
Where do these wrong "formats" come from ?
Because created_at is a DateTime, rails using time formats (not date).
https://github.com/svenfuchs/rails-i18n/blob/master/rails/locale/en.yml#L195
time:
am: am
formats:
default: ! '%a, %d %b %Y %H:%M:%S %z'
Type in your console
I18n.t(:"date")
to check if you are getting the translations you defined in your translation .yml file.
Compare the structure with the standard EN locale
I18n.t(:"date", locale:'en')
That made me notice I was declaring the date: attribute twice in my .yml, and the first part was being overwritten by the second declaration.
You should get the abbr_month_names that you declared when calling
I18n.t(:"date.abbr_month_names")
These are the ones that will be used when calling %b.
If not, check your locale .yml file to make sure they are properly declared, and not being declared twice.
You may also call I18n.locale to check if the .yml file you are editing is the one being used by rails

Strange I18n date output with rails

I've got a strange problem with date translations in my Ruby On Rails 3 application, and I really don't understand why...
Here are my en.yml and fr.yml :
fr:
date:
formats:
default: "%d/%m/%Y"
short: "%e %b"
long: "%e %B %Y"
time:
formats:
default: "%d %B %Y %H:%M:%S"
short: "%d %b %H:%M"
long: "%A %d %B %Y %H:%M"
am: 'am'
pm: 'pm'
en:
date:
formats:
default: "%Y-%m-%d"
long: "%B %d, %Y"
short: "%b %d"
time:
am: am
formats:
default: ! '%a, %d %b %Y %H:%M:%S %z'
long: ! '%B %d, %Y %H:%M'
short: ! '%d %b %H:%M'
pm: pm
This is not specific to a particuliar view, but for instance in one of my view :
<td><%=l job_application.created_at, :format => :default %></td>
I get those strange outputs :
With locale = :en
=> t, 30 o 2012 18:09:33 +0000
With locale = :fr
=> 30 o 2012 18:09:33
Where do these wrong "formats" come from ?
I'm using Rails 3.2.8 (with Postgresql / gem pg), and everything related to I18n works fine except for dates.
Thanks for any help !
I think I've finally figured this out, sorry for taking so long.
The Rails l helper just calls I18n.localize. If you trace through the I18n.localize code, you'll end up here:
format = format.to_s.gsub(/%[aAbBp]/) do |match|
case match
when '%a' then I18n.t(:"date.abbr_day_names", :locale => locale, :format => format)[object.wday]
when '%A' then I18n.t(:"date.day_names", :locale => locale, :format => format)[object.wday]
when '%b' then I18n.t(:"date.abbr_month_names", :locale => locale, :format => format)[object.mon]
when '%B' then I18n.t(:"date.month_names", :locale => locale, :format => format)[object.mon]
when '%p' then I18n.t(:"time.#{object.hour < 12 ? :am : :pm}", :locale => locale, :format => format) if object.respond_to? :hour
end
end
So the localize helper doesn't use strftime for the "stringy" parts of the date/time, it tries to do it by itself. Add the translations (as arrays in your YAML) for the month and day names as above and your localized dates and times should start working.
If you don't have those translation arrays in your YAML, then I18n.t(:"date.abbr_month_names") will give you strings like this:
"translation missing: en.date.abbr_month_names"
and then I18n.localize will end up doing silly things like this:
"translation missing: en.date.abbr_month_names"[10]
That will use String#[] instead of the expected Array#[] and you end up with random looking single character month and day names.
Where do these wrong "formats" come from ?
Because created_at is a DateTime, rails using time formats (not date).
https://github.com/svenfuchs/rails-i18n/blob/master/rails/locale/en.yml#L195
time:
am: am
formats:
default: ! '%a, %d %b %Y %H:%M:%S %z'
Type in your console
I18n.t(:"date")
to check if you are getting the translations you defined in your translation .yml file.
Compare the structure with the standard EN locale
I18n.t(:"date", locale:'en')
That made me notice I was declaring the date: attribute twice in my .yml, and the first part was being overwritten by the second declaration.
You should get the abbr_month_names that you declared when calling
I18n.t(:"date.abbr_month_names")
These are the ones that will be used when calling %b.
If not, check your locale .yml file to make sure they are properly declared, and not being declared twice.
You may also call I18n.locale to check if the .yml file you are editing is the one being used by rails

Rails not picking up custom date & time formats in en.yml

I'm not that familiar with I18N in Rails so bear with me. Trying to set a custom date & time format:
#config/locales/en.yml
en:
date:
formats:
long_dateweek: "%A, %B %d, %Y"
time:
formats:
very_short: "%H:%M"
But when I try to use them I just get the default formats:
1.9.3p194 :001 > Time.now.to_date.to_s(:long_dateweek)
=> "2012-08-22"
1.9.3p194 :002 > Time.now.to_time.to_s(:very_short)
=> "2012-08-22 16:12:47 -0700"
Tried restarting console (and even the server) to no avail... What'd I miss?
You need to use the I18n.l method as follows:
1.9.3p194 :001 > I18n.l Time.now.to_date, :format => :long_dateweek
=> "Wednesday, August 22, 2012"
1.9.3p194 :002 > I18n.l Time.now, :format => :very_short
=> "23:03"
You can also use the l helper method in your views. Look at this rails guide for more information.
#alexsanford1 has the right answer. I modified mine below to work in the view.
<%= l Time.now, :format => :very_short %>

Localize a whole sentense passing it a datetime

I googled around but didn't find an answer - even if I guess it isn't tricky!
I'd like to localize a sentense that icludes date and time parameter. I want to pass it a complete datetime.
de_txt.yml
de:
article:
will_be_published_at: 'Wartet auf Veröffentlichung am %a %e. %b %Y um %H:%M Uhr'
My function with d is out of the database, field type is datetime
(second line is the one of my problem)
def icon_article_will_be_published_at(d)
alt = t('article.will_be_published_at', d)
image_tag("#{root_url}images/famfamfam/icons/date_next.png", :title => alt, :alt => alt, :class => "icon")
end
more about d
d.inspect # => Sat, 03 Dec 2011 14:07:00 CET +01:00
I can't figure it out and would appreciate help.
For this, you will need the I18n#l method, not the translate method.
It's a bit tricky, because you need a separate time format in the translations file (de.yml). This is one way to do it (adjust as necessary):
In config/locales/de.yml:
de:
time:
formats:
article_published_at: 'Wartet auf Veröffentlichung am %a %e. %b %Y um %H:%M Uhr'
Testing it in the console:
I18n.locale = :de
I18n.l Time.now, :format => :article_published_at
I would propose the following:
Split what you want to do in 2 steps:
Define a special format :um as described in the Rails Guide to I18n
de:
article:
will_be_published_at: 'Wartet auf Veröffentlichung am %datetime'
time:
formats:
um: "%a %e. %b %Y um %H:%M Uhr"
Call it then in the following snippet:
time = l(d, :format => :um)
alt = t('article.will_be_published_at', :datetime => time)
I could not test it, but it should work.

Month names inflection in Rails I18n

I would like to use different case of month name in Polish. For example now it works like this:
>> I18n.l Time.now, :format => "%e %B"
=> "14 styczeń"
but I would like to specify another format of month:
>> I18n.l Time.now, :format => "%e %Q"
=> "14 stycznia"
Translated month names are in my pl.yml file in pl.date.month_names. And I don't want to change it. I can add pl.date.another_month_names in the other case, but I don't know how to make I18n.l method to use it.
So how can I achive that? Other solutions (helpers, custom methods etc.) are also welcome.
i had a similar problem with strange month names in german translation.
I had to configure the month names in my locale.yml, now it works as expected:
de:
defaults: &defaults
month_names:
[~, Januar, Februar, März, April, Mai, Juni, Juli, August, September, Oktober, November, Dezember]
formats:
default: "%d. %B %Y"
short: "%d.%m.%Y"
date:
<<: *defaults
time:
<<: *defaults
Since nobody answered my question, I found one solution.
I just created another translation, for example alt_pl.yml and I added my custom month names, then:
>> I18n.l Time.now, :format => "%e %Q", :locale => :alt_pl
=> "15 stycznia"

Resources