2011-03-20 55 views
22

根据文档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.yml中定制日期时间格式在Rails 3中

我做了一些改变(星号表示强调只):

"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的“short”或“long”的定义。我试图通过添加以下代码将其添加到此文件中:

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

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

+0

什么是运行'item.create_date.class'上的结果'轨console'(?或只是为之倾倒在屏幕上) – 2011-03-20 06:48:59

+0

我得到:的ActiveSupport :: TimeWithZone – panzhuli 2011-03-20 13:34:27

回答

5

[几年后...]

如果你要干你的日期格式和/或你有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' 
8

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

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

    日期时间:: DATE_FORMATS [:短] =“短%Y-%间%d%H:%M:%S”

    时间:: DATE_FORMATS [:短] = “短%Y-%间 - %d%H:%M:%S”

    日期:: DATE_FORMATS [:short] =“short%Y-%m-%d”

  2. 修改视图:

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

你可以看到输出的变化,以 “短的东西”。

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

+0

这确实的现在的技巧 - 谢谢:) – panzhuli 2011-03-20 16:15:24

32

[几个月后...]

的问题是,你要定义一个en.yml“日期时间”的格式,但Rails的本地化代码只检查“日期”或“时间“(将”datetime“与”time“结合起来)。

有问题的代码是在I18N基码here,在线路53:

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

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

正如Tyrael建议的那样,您可以通过初始化代码强制它遵守您的意愿。这肯定会起作用,但现在您已经将本地化代码放入了您的初始化程序。这可能会令人困惑和混乱,国际海事组织。

IMO,更清洁的方式做到这一点是通过指定一个不同的“格式”您要为日期时间格式添加到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 %> 

这会使您的本地化信息保留在您的本地化文件中,但它需要让您的手变脏(代码abo ve并没有做任何错误检查,不接受参数等),并强制你使用一个不同的函数来输出它(而不是仅仅是“l”,一个很长的“ld”)。

最后(也许最少),我们可以告诉Rails gnome修复该函数,以便允许“datetime”。 :)

希望是有用的。祝你好运。

+3

这是有益的感谢。只是想为其他人添加一个音符(使我绊倒的东西):'item.created_at。to_s(:short_datetime)'将*不*执行本地化。你必须用'l item.create_date,:format =>:short_datetime'这样的'''方法实际调用它。谢谢! – 2012-06-03 23:06:16

+0

你的'%B'也翻译了吗?实际上我试图通过I18N本地化月份名称 - 到目前为止没有成功。 – knut 2013-01-02 15:39:25

0

只是想澄清的是,如果你有活动记录使用,只需简单的字符串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) %>