【问题标题】:Strange I18n date output with rails带导轨的奇怪 I18n 日期输出
【发布时间】:2012-09-21 18:12:04
【问题描述】:

我的 Ruby On Rails 3 应用程序中的日期翻译有一个奇怪的问题,我真的不明白为什么......

这是我的en.ymlfr.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

这不是特定于特定视图,而是例如在我的一个视图中:

<td><%=l job_application.created_at, :format => :default %></td>

我得到了那些奇怪的输出:

With locale = :en
=> t, 30 o 2012 18:09:33 +0000

With locale = :fr
=> 30 o 2012 18:09:33

这些错误的“格式”从何而来?

我使用的是 Rails 3.2.8(使用 Postgresql / gem pg),与 I18n 相关的所有内容都可以正常工作,日期除外

感谢您的帮助!

【问题讨论】:

  • 是的,我也有...(更新后)
  • 输出匹配格式字符串的次数,除了字符串部分被截断为一个字符?知道o 来自哪里吗?格式化的版本应该是什么?
  • 不完全是,单个字符并不总是月份或日期名称的第一个字母。例如:Mon, 01 Oct 2012 17:11:55 UTC +00:00 将被翻译成:“01 n 2012 17:11:55”
  • 如果您手动将这些格式与strftime 一起使用会怎样?
  • 它与 strftime 配合得很好......

标签: ruby-on-rails ruby-on-rails-3 date localization internationalization


【解决方案1】:

我想我终于想通了,抱歉花了这么长时间。

Rails l 助手只是调用I18n.localize。如果你跟踪I18n.localize 代码,你最终会得到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

因此,localize 助手不会将strftime 用于日期/时间的“字符串”部分,它会尝试自行完成。为上述月份和日期名称添加翻译(作为 YAML 中的数组),您的本地化日期和时间应该开始工作了。

如果你的 YAML 中没有这些翻译数组,那么 I18n.t(:"date.abbr_month_names") 会给你这样的字符串:

"translation missing: en.date.abbr_month_names"

然后I18n.localize 最终会做这样的傻事:

"translation missing: en.date.abbr_month_names"[10]

这将使用String#[] 而不是预期的Array#[],您最终会得到随机的单字符月份和日期名称。

【讨论】:

  • 感谢您的回答,我找到了问题!实际上,我的翻译文件中有所有 "date.abbr_day_names" / "date.abbr_month_names" / ... 键,但我已经覆盖了 "date" 键来翻译 "date" 单词(没有命名空间的全局键)!我知道不是很聪明...感谢您的宝贵时间!
  • “为上述月份和日期名称添加翻译(作为 YAML 中的数组),您的本地化日期和时间应该开始工作。”什么?在哪里?很抱歉,我不明白,有人可以提供一个例子吗?
【解决方案2】:

这些错误的“格式”从何而来?

因为created_at 是一个日期时间,所以rails 使用time 格式(不是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'

【讨论】:

    【解决方案3】:

    在你的控制台输入

    I18n.t(:"date") 
    

    检查您是否获得了您在翻译.yml 文件中定义的翻译。

    将结构与标准 EN 语言环境进行比较

    I18n.t(:"date", locale:'en')
    

    这让我注意到我在.yml 中两次声明了date: 属性,第一部分被第二个声明覆盖。

    你应该得到你调用时声明的abbr_month_names

    I18n.t(:"date.abbr_month_names")
    

    这些是调用%b 时将使用的那些。

    如果没有,请检查您的语言环境.yml 文件以确保它们被正确声明,并且没有被声明两次。

    您也可以调用I18n.locale 来检查您正在编辑的.yml 文件是否是rails 正在使用的文件

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-01
      • 1970-01-01
      • 2015-03-05
      • 1970-01-01
      • 2013-09-18
      • 1970-01-01
      • 2020-02-05
      • 1970-01-01
      相关资源
      最近更新 更多