How to translate date in rspec rails - ruby-on-rails

I am trying to translate a date in full into my language but I am getting I18n error.
The code below give me an answer in English (standard)
expect(page).to have_content 1.day.from_now.strftime("%d de %B de %Y %H:%M")
If I use localize to translate the following code I got the error:
I18n::ArgumentError:
Object must be a Date, DateTime or Time object. "13 de February de 2023 20:00" given.
expect(page).to have_content I18n.l(1.day.from_now.strftime("%d de %B de %Y %H:%M"))
The view is already translated, no issues in view:
<h2>Refeição em <%= I18n.l ml.meal_date, :format => "%d de %B de %Y %H:%M" %></h2>
So how's the correct way to get the date correctly translated into RSPEC?

Don't do dynamic tests in RSpec. It is preferable to have an expected output ex. comparing String to String
You can stub the exact date you want to test for example using the Timecop gem, render the page, then simply use assert_select <css-selector>, label:<Expected text>
it "have english time format" do
new_time = Time.local(2023, 2, 13, 20, 0, 0)
Timecop.freeze(new_time)
# code to render your page
assert_select 'h2', label: '13 de February de 2023 20:00', count: 1
end

Related

Day name with I18n

Without translation, this would get me today's day name:
Date.today.strftime("%A")
How would I localize it?
I.e. "Mardi" if I18n.locale is set to fr.
You probably have in your locale file(s) the following:
# example with fr
fr:
date:
day_names: [Dimanche, Lundi, Mardi, Mercredi, Jeudi, Vendredi, Samedi]
# ^^^^^^^^ a week starts with a Sunday, not a Monday
In order to get today's name, you could do:
week_day = Date.today.wday # Returns the day of week (0-6, Sunday is zero)
I18n.t('date.day_names')[week_day]
or eventually
I18n.l(Date.today, format: '%A')
l Date.today, format: "%A"
Will work if you have the day_names in your translation file.
if you use rails-i18n, you will have the day names and month names already translated, e.g.:
I18n.l(value, format: "le %A %e %B à %-Hh%M")
# le Dimanche 19 Juillet à 21h00

Rails - using capitalize on a month name from l18n

I have a string like this in my view
<%= l event.start_date, format: :long %>
which outputs
18 aout 2013
I would like to capitalize the month name without touching the yaml file, and tried several options which failed miserably. Is it possible?
If you call capitalize it only takes the first character, so you may use titleize
<%=(l Date.today, format: :long) %>
=> "Miércoles, 28 de agosto de 2013"
<%=(l Date.today, format: :long).titleize %>
=> "Miércoles, 28 De Agosto De 2013"
Please note that all the words are turned to capital letter
Update
$ rails c
Loading development environment (Rails 4.0.0)
>> helper.l Date.today, format: :long
=> "September 02, 2013"
>> helper.l Time.now, format: :long
=> "September 02, 2013 22:56"

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.

AM/PM not uppercase when using I18n.l with %p in Rails

I'm having an issue which I can't seem to figure out. I'm trying to format a date using a custom format I've defined in my en.yml file:
en:
hello: "Hello world"
time:
formats:
history_table: "%m/%d/%Y %I:%M:%S %p %Z"
This is being called using the 'l' helper:
l version.created_at, :format => :history_table
For some reason this is displaying the AM/PM in lowercase, instead of in uppercase as should be the case with %p.
I've played around in the console a bit, and it seems like it's a difference in behavior between the localization function and strftime:
ruby-1.9.2-p180 :043 > I18n.l user.updated_at, :format => "%m/%d/%Y %I:%M:%S %p %Z"
=> "03/23/2011 01:52:16 am UTC"
ruby-1.9.2-p180 :044 > user.updated_at.strftime("%m/%d/%Y %I:%M:%S %p %Z")
=> "03/23/2011 01:52:16 AM UTC"
Am I doing something wrong? Is this a bug? Any guidance is greatly appreciated as my forehead is sore from banging it against the wall.
Edit:
This has been solved(ish).
Looking at the default activesupport localization, there isn't any differentiation between %p and %P.
https://github.com/rails/rails/blob/master/activesupport/lib/active_support/locale/en.yml
I over-rode the localization in my local en.yml file to use uppercase. I would really have liked to see Rails support both options however.
Looking in the source for active support, I found the following under english localization:
time:
formats:
default: "%a, %d %b %Y %H:%M:%S %z"
short: "%d %b %H:%M"
long: "%B %d, %Y %H:%M"
am: "am"
pm: "pm"
In other words, there is no distinction between %P and %p built-in to localization as there is in strftime. This unfortunately means that in individual custom formats it is not possible to choose between upper and lower case representations, but it is possible to define which you would like globally by over-riding the default formats in your own en.yml file. For example, here's my updated en.yml file that now causes the output of upper-case AM/PM.
en:
hello: "Hello world"
time:
formats:
history_table: "%m/%d/%Y %I:%M:%S %p %Z"
am: "AM"
pm: "PM"

Rails: How to make Date strftime aware of the default locale?

I have my default locale set in the environment.rb as de (German).
I also see all the error messages in German, so the locale is picked up by the server. But when I try to print date with strftime like following:
some_date.strftime('%B, %y')
It prints in English (January, 11), and not the expected German (Januar, 11).
How can I print the date according to the default locale?
Use the l (alias for localize) method instead of raw strftime, like this:
l(date, format: '%B %d, in the year %Y')
See here for more information.
You can also define 'named' formats, a couple of them (short, long) are already predefined.
you can also make it shorter:
l(some_date, :format => '%d %B %Y')
In es.yml put:
es:
date:
formats:
default: "%d / %m / %Y"
In index.html.erb put:
<%= l somemodel.datefield %>

Resources