2008-10-03 25 views
163

我想按照以下格式顯示日期:短週日,短月,不含前導零但包含「th」,「st」,「nd」或「rd」後綴的月份。在Ruby on Rails中,如何使用「th」後綴格式化日期,如「Sun Oct 5th 5th」中的日期?

例如,這個問題被問到的那一天將顯示「Thu Oct 2nd」。

我使用的是Ruby 1.8.7,而Time.strftime似乎沒有這樣做。如果存在的話,我更喜歡標準庫。

+2

您可能希望在您的問題或標題中使用「後綴」一詞,以使其他人更容易找到。在談論日期時,我不確定是否有另一個字。 – 2008-10-03 00:16:12

+0

優秀的問題。我幾天前纔想到同樣的事情 - 非常有幫助。 – RichH 2008-10-03 18:10:34

回答

254

使用'active_support'的ordinalize方法。

>> time = Time.new 
=> Fri Oct 03 01:24:48 +0100 2008 
>> time.strftime("%a %b #{time.day.ordinalize}") 
=> "Fri Oct 3rd" 

請注意,如果您使用的IRB使用Ruby 2.0,你必須首先運行:

require 'active_support/core_ext/integer/inflections' 
+13

請注意,這不在標準庫中。 – 2011-02-01 11:34:26

90

您可以在數字上使用active_support的ordinalize幫助器方法。

>> 3.ordinalize 
=> "3rd" 
>> 2.ordinalize 
=> "2nd" 
>> 1.ordinalize 
=> "1st" 
9
>> require 'activesupport' 
=> [] 
>> t = Time.now 
=> Thu Oct 02 17:28:37 -0700 2008 
>> formatted = "#{t.strftime("%a %b")} #{t.day.ordinalize}" 
=> "Thu Oct 2nd" 
5

我喜歡巴爾託什的答案,但是,嘿,因爲這是我們正在談論的Rails ,讓我們以狡猾的眼光來看待它。 (編輯:雖然我只打算猴補丁以下的方法,原來有一個清潔的方式。)

DateTime實例具有由的ActiveSupport供給的to_formatted_s方法,它只需一個符號作爲一個參數,並且如果該符號被識別爲有效的預定義格式,並返回具有適當格式的字符串。

這些符號由Time::DATE_FORMATS定義,它是符號散列到標準格式化函數的字符串...或者特效。 Bwahaha。

d = DateTime.now #Examples were executed on October 3rd 2008 
Time::DATE_FORMATS[:weekday_month_ordinal] = 
    lambda { |time| time.strftime("%a %b #{time.day.ordinalize}") } 
d.to_formatted_s :weekday_month_ordinal #Fri Oct 3rd 

但是,嘿,如果你無法抗拒的機會,猴補丁,你總是可以給一個簡潔的界面:

class DateTime 

    Time::DATE_FORMATS[:weekday_month_ordinal] = 
     lambda { |time| time.strftime("%a %b #{time.day.ordinalize}") } 

    def to_my_special_s 
    to_formatted_s :weekday_month_ordinal 
    end 
end 

DateTime.now.to_my_special_s #Fri Oct 3rd 
26

以帕特里克·麥肯齊的回答只是遠一點,你可以創建一個在config/initializers目錄中的新文件名爲date_format.rb(或任何你想要的),並把這個在它:在您的視圖代碼,您可以格式化

Time::DATE_FORMATS.merge!(
    my_date: lambda { |time| time.strftime("%a, %b #{time.day.ordinalize}") } 
) 

然後只需簡單地將它指定爲新的日期格式即可:

My Date: <%= h some_date.to_s(:my_date) %> 

它很簡單,它的工作原理很容易構建。只需在date_format.rb文件中爲每種不同的日期格式添加更多格式行即可。這是一個更加充實的例子。

Time::DATE_FORMATS.merge!(
    datetime_military: '%Y-%m-%d %H:%M', 
    datetime:   '%Y-%m-%d %I:%M%P', 
    time:    '%I:%M%P', 
    time_military:  '%H:%M%P', 
    datetime_short: '%m/%d %I:%M', 
    due_date: lambda { |time| time.strftime("%a, %b #{time.day.ordinalize}") } 
)