在Rails 3中的en.yml中自定义日期时间格式

pan*_*uli 23 datetime internationalization ruby-on-rails-3

根据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到我的locales目录.

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

"en-US":
  date:
    formats:
      default: "%Y-%m-%d"
      **short: "short %b %d"**
Run Code Online (Sandbox Code Playgroud)

time:
    formats:
      default: "%a, %d %b %Y %H:%M:%S %z "
      **short: "short %B %d, %Y"**
Run Code Online (Sandbox Code Playgroud)

在我的部分:

<%= l item.create_date, :format => :short %>
Run Code Online (Sandbox Code Playgroud)

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

我重新启动了我的服务器,但仍然得到这样的日期:15月00日00:00

我觉得这是因为我既不使用日期也不使用时间.我找不到datetime的"short"或"long"的定义.我尝试通过添加以下代码将其添加到此文件中:

datetime:
    formats:
      short: "short %B %d, %Y"
Run Code Online (Sandbox Code Playgroud)

没运气.我错过了什么 我觉得我直接按照说明操作.谢谢!

小智 33

[几个月后......]

问题是你试图在en.yml中定义"日期时间"格式,但Rails本地化代码只检查"日期"或"时间"(将"datetime"与"time"结合在一起).

有问题的代码是在国际化的基本代码在这里,在第53行:

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

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

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

IMO,更简洁的方法是通过指定不同的'格式',将DateTime所需的格式添加到en.yml的'time'部分,如下所示:

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...
Run Code Online (Sandbox Code Playgroud)

您可以这样使用:

<%= l item.create_date, :format => :short_datetime %>
Run Code Online (Sandbox Code Playgroud)

这就是我自己使用的方法.

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

en:
  datetime:
    formats:
      default: %B %d, %Y
Run Code Online (Sandbox Code Playgroud)

然后告诉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...
Run Code Online (Sandbox Code Playgroud)

然后像这样使用它:

<%= ld item.create_date %>
Run Code Online (Sandbox Code Playgroud)

这会将您的本地化信息保存在您的本地化文件中,但它需要弄脏您的手(上面的代码不做任何错误检查,不接受参数等),并强制您使用不同的函数输出它(而不仅仅是"l",一个痛苦的长"ld").

最后(也可能是最不重要),我们可以告诉Rails gnomes修复该功能,因此它允许"datetime".:)

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

  • 这非常有用,谢谢.只想为其他人添加一个注释(让我感到惊讶的是):`item.created_at.to_s(:short_datetime)`将*不*进行本地化.你必须使用`l`方法调用它,如`l item.create_date,:format =>:short_datetime`.谢谢! (3认同)

Tyr*_*ong 8

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

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

    DateTime :: DATE_FORMATS [:short] ="短%Y-%m-%d%H:%M:%S"

    时间:: DATE_FORMATS [:短] ="短%Y-%m-%d%H:%M:%S"

    Date :: DATE_FORMATS [:short] ="short%Y-%m-%d"

  2. 修改视图:

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

您可以看到输出更改为"短路".

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


Phi*_*ilT 6

[几年后......]

如果您想要删除日期格式和/或您拥有遗留代码to_s并且不打算将应用程序国际化,则可以执行以下操作:

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

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

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

require 'active_support/time'
I18n.load_path << 'en.yml'
Run Code Online (Sandbox Code Playgroud)