在 RubyonRails 中,如何用“ th”后缀格式化日期,比如“ SunOct5th”?

我希望以这样的格式显示日期: 每周的短日期、月份的短日期、月份的短日期,前面没有零,但是包括“ th”、“ st”、“ nd”或“ rd”后缀。

例如,提出这个问题的那天会显示“ Thu Oct 2 nd”。

我使用的是 Ruby 1.8.7,而 时间,时间似乎不能做到这一点。如果存在标准库的话,我更喜欢它。

53798 次浏览

可以对数字使用 active _ support 的 ordinalize helper 方法。

>> 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"

注意,如果你在 Ruby 2.0中使用 IRB,你必须首先运行:

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,那么我们就更进一步。(编辑: 虽然我打算用 monkeypatch 修补下面的方法,但结果发现有一种更干净的方法。)

DateTime实例具有 ActiveSupport 提供的 to_formatted_s方法,该方法接受单个符号作为参数,如果该符号被识别为有效的预定义格式,则返回具有适当格式的 String。

这些符号由 Time::DATE_FORMATS定义,Time::DATE_FORMATS是标准格式化函数的字符串或 procs 的符号哈希表。哇哈哈。

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}") }
)

创建自己的 %o格式。

初始化程序

config/initializers/srtftime.rb

module StrftimeOrdinal
def self.included( base )
base.class_eval do
alias_method :old_strftime, :strftime
def strftime( format )
old_strftime format.gsub( "%o", day.ordinalize )
end
end
end
end


[ Time, Date, DateTime ].each{ |c| c.send :include, StrftimeOrdinal }

用法

Time.new( 2018, 10, 2 ).strftime( "%a %b %o" )
=> "Tue Oct 2nd"

你也可以把它和 DateDateTime一起使用:

DateTime.new( 2018, 10, 2 ).strftime( "%a %b %o" )
=> "Tue Oct 2nd"


Date.new( 2018, 10, 2 ).strftime( "%a %b %o" )
=> "Tue Oct 2nd"

虽然 Jonathan Tran 说他正在寻找缩写的星期一,然后是缩写的月份,但是我认为对于那些最终来到这里的人来说,了解 Rails 支持更常用的长月份,有序的日整数,然后是年份,这可能是有用的。

这可以很容易地实现:

Time.current.to_date.to_s(:long_ordinal)
=> "January 26th, 2019"

或者:

Date.current.to_s(:long_ordinal)
=> "January 26th, 2019"

如果你愿意,你也可以坚持一个时间实例:

Time.current.to_s(:long_ordinal)
=> "January 26th, 2019 04:21"

您可以在 Rails API 文档中找到关于如何创建自定义格式的更多格式和上下文。