在Ruby on Rails中,如何格式化带有" th"后缀的日期,例如" Sun Oct 5th"?
时间:2020-03-06 15:03:25 来源:igfitidea点击:
我想以以下格式显示日期:周的短日,短的月,月中的日期,且不带前导零,但包括" th"," st"," nd"或者" rd"后缀。
例如,询问该问题的日期将显示" 10月2日星期四"。
我正在使用Ruby 1.8.7,而Time.strftime似乎没有执行此操作。我希望有一个标准库。
解决方案
我们可以对数字使用active_support的序数化帮助器方法。
>> 3.ordinalize => "3rd" >> 2.ordinalize => "2nd" >> 1.ordinalize => "1st"
使用'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'
>> require 'activesupport' => [] >> t = Time.now => Thu Oct 02 17:28:37 -0700 2008 >> formatted = "#{t.strftime("%a %b")} #{t.day.ordinalize}" => "Thu Oct 2nd"
我喜欢Bartosz的答案,但是,嘿,既然这是我们正在谈论的Rails,那么就让它迈开一步。 (编辑:尽管我只是简单地修补以下方法,但事实证明这是一种更干净的方法。)
" DateTime"实例具有ActiveSupport提供的" to_formatted_s"方法,该方法将单个符号作为参数,并且如果该符号被识别为有效的预定义格式,则返回具有适当格式的String。
这些符号由Time :: DATE_FORMATS
定义,它是符号到标准格式设置函数或者proc字符串的哈希。哇哈哈哈
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
再接一点Patrick McKenzie的回答,我们可以在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}") } )