2011-03-20 67 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) %>