2008-10-03 33 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}") } 
)