【问题标题】:Customizing datetime format in en.yml in Rails 3在 Rails 3 中自定义 en.yml 中的日期时间格式
【发布时间】:2011-07-19 00:05:00
【问题描述】:

根据http://guides.rubyonrails.org/i18n.html#adding-date-time-formats 的文档,询问特定日期格式的最佳方法是在/config/locales/en.yml 中定义它们。我已将此文件:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/locale/en.yml 复制并粘贴到我的语言环境目录中。

我做了一些更改(星号仅用于强调):

"en-US":
  date:
    formats:
      default: "%Y-%m-%d"
      **short: "short %b %d"**

time:
    formats:
      default: "%a, %d %b %Y %H:%M:%S %z "
      **short: "short %B %d, %Y"**

在我的部分:

<%= l item.create_date, :format => :short %>

create_date 是我的项目数据库中的日期时间行。

我已经重新启动了我的服务器,但仍然收到如下格式的日期: 3月15日00:00

我有一种感觉,这是因为我既没有使用日期也没有使用时间。我找不到日期时间的“短”或“长”的定义。我尝试通过添加以下代码将其添加到此文件中:

datetime:
    formats:
      short: "short %B %d, %Y"

运气不好。我错过了什么。我觉得我直接按照说明进行操作。谢谢!

【问题讨论】:

  • rails console 上运行item.create_date.class 的结果是什么(或者只是将其转储到屏幕上?)
  • 我得到:ActiveSupport::TimeWithZone

标签: ruby-on-rails-3 datetime internationalization


【解决方案1】:

我怀疑这里的问题出在 Rails 的 I18n:l 函数中。试试这个:

  1. 将以下行添加到您的初始化程序文件之一,例如 config/environment.rb:

    DateTime::DATE_FORMATS[:short]="short %Y-%m-%d %H:%M:%S"
    
    Time::DATE_FORMATS[:short] = "short %Y-%m-%d %H:%M:%S"
    
    Date::DATE_FORMATS[:short] = "short %Y-%m-%d"
    
  2. 修改视图:

    <%= item.create_date.to_s(:short) %>
    

您可以看到输出更改为“short something”。

我知道这不是一个完美的答案,但希望它能给你一些提示(我没有时间检查 I18n::l 函数)。

【讨论】:

    【解决方案2】:

    只是想澄清一下,如果您使用活动记录,只需将字符串 datetime 值转换为 date 对象,如下例所示。

    en:
      date:
        formats:
          default: "%Y-%m-%d"
          short: "%b %d"
          long: "%B %d, %Y"
        
    

    <%= l(post.the_created_at.to_date, format: :long) %>
    

    【讨论】:

      【解决方案3】:

      [几个月后...]

      问题在于您试图在 en.yml 中定义“日期时间”格式,但 Rails 本地化代码仅检查“日期”或“时间”(将“日期时间”与“时间”混为一谈)。

      违规代码在 i18n 基础代码here 中,第 53 行:

      type = object.respond_to?(:sec) ? 'time' : 'date'

      它检查给定对象是否可以响应“sec”;如果是,它会读取 en.yml 中的“时间”内容,如果不是,它会读取“日期”格式。没有“日期时间”。

      正如泰瑞尔建议的那样,你可以通过初始化代码强制它在枪口下服从你的意志。这肯定会奏效,但现在您已将本地化代码放入初始化程序中。这可能会造成混乱和混乱,IMO。

      IMO,一种更简洁的方法是通过指定不同的“格式”将您想要的 DateTime 格式添加到 en.yml 的“时间”部分,如下所示:

      en:
        time:
          formats:
            short_datetime: %B %d, %Y
            long_datetime:  %B %d, %Y, at %r
            hammer_datetime: STOP! %B %d, %Y, is HAMMERTIME!
            # and so on... da dum... da dum...
      

      你可以这样使用:

      <%= l item.create_date, :format => :short_datetime %>
      

      这是我自己使用的方法。

      但为了完整起见,您也可以这样做:

      en:
        datetime:
          formats:
            default: %B %d, %Y
      

      然后告诉 Rails 如何读取它,像这样:

      # In your Application Helper
      def localize_datetime(dt)
        # quick-and-dirty demo... doesn't accept different format options and stuff...
        dt.strftime(I18n.t(:"datetime.formats.default", {:locale => I18n.locale }))
      end
      def ld(dt)
        localize_datetime(dt)
      end
      # or something like that...
      

      然后像这样使用它:

      <%= ld item.create_date %>
      

      这会将您的本地化信息保留在您的本地化文件中,但需要亲自动手(上面的代码不进行任何错误检查,不接受参数等),并迫使您使用不同的功能用于输出它(而不仅仅是“l”,一个令人痛苦的长“ld”)。

      最后(可能是最不重要的),我们可以告诉 Rails gnome 修复该功能,以便它允许“日期时间”。 :)

      希望这很有用。祝你好运。

      【讨论】:

      • 这很有帮助,谢谢。只是想为其他人添加一个注释(这让我感到困惑):item.created_at.to_s(:short_datetime)进行本地化。您必须使用l 方法(如l item.create_date, :format =&gt; :short_datetime)实际调用它。谢谢!
      • 你的%B也翻译了吗?我实际上正在尝试通过 I18N 本地化月份名称 - 到目前为止没有成功。
      【解决方案4】:

      [几年后...]

      如果您想干掉您的日期格式和/或您到处都有带有to_s 的旧代码并且不打算将您的应用国际化,您可以这样做:

      I18n.t('date.formats').each do |key, value|
        Date::DATE_FORMATS[key] = value
      end
      

      然后在config/locales/en.yml 中定义您的格式。当然,如果您打算翻译您的应用程序,则需要更改所有出现的 to_s 以使用下面建议的 I18n.l 方法。

      你也可以在没有 Rails 的情况下使用它。只需在上述代码前添加以下内容:

      require 'active_support/time'
      I18n.load_path << 'en.yml'
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-05-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-17
        • 1970-01-01
        相关资源
        最近更新 更多