ruby-i18n / i18n

Internationalization (i18n) library for Ruby
MIT License
977 stars 408 forks source link

[BUG] `%P` gets stripped from `localize` formats for `Date` objects #639

Closed movermeyer closed 1 year ago

movermeyer commented 1 year ago

What I tried to do

(byebug) date = Date.new(2018, 12, 26)
Wed, 26 Dec 2018
(byebug) date.to_datetime.iso8601
"2018-12-26T00:00:00+00:00"
(byebug) I18n.locale = :en
:en
(byebug) I18n.l(date, format: :friendly_date_time)
en:
  date:
    formats:
      friendly_date_time: "%b %-d, %Y, %-l:%M %P"

What I expected to happen

"Dec 26, 2018, 12:00 am"

What actually happened

"Dec 26, 2018, 12:00 "

The resulting datetime is 12 hours off, since without the Meridian indicator (i.e., am/pm), it can only be reasonably interpreted as a 24-hour clock datetime.

Versions of i18n, rails, and anything else you think is necessary

Explanation

I18::Backend::Base#translate_localization_format strips %p/%P unless object.respond_to?(:hour). Date#hour is a private method, so object.respond_to?(:hour) is false, despite Date#strftime supporting the %p/%P fields:

date.strftime("%b %-d, %Y, %-l:%M %P")
"Dec 26, 2018, 12:00 am"

This conditional was added in this commit (2008-06-17).

radar commented 1 year ago

What an obscure catch this is :)

Thank you very much for taking the time to investigate the issue and submit a fix as well.