在Ruby on Rails中,如何使用"th"后缀格式化日期,如"Sun Oct 5th"?

Jon*_*ran 174 ruby ruby-on-rails date

我希望以以下格式显示日期:短星期,短月,月中没有前导零但包括"th","st","nd"或"rd"后缀.

例如,问这个问题的那天会显示"Thu Oct 2nd".

我正在使用Ruby 1.8.7,而Time.strftime似乎并没有这样做.如果存在标准库,我更喜欢它.

Bar*_*mke 272

使用'active_support'中的ordinalize方法.

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

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

require 'active_support/core_ext/integer/inflections'
Run Code Online (Sandbox Code Playgroud)

  • 请注意,这不在标准库中. (14认同)

mwi*_*ams 94

您可以对数字使用active_support的ordinalize辅助方法.

>> 3.ordinalize
=> "3rd"
>> 2.ordinalize
=> "2nd"
>> 1.ordinalize
=> "1st"
Run Code Online (Sandbox Code Playgroud)

  • 现在已经是 2020 年了,仍然是这样的事情让我爱上了 Rails。 (2认同)

Ric*_*urt 30

再拿Patrick McKenzie的答案,您可以在您的config/initializers目录中创建一个名为date_format.rb(或任何您想要的)的新文件并将其放入其中:

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

然后在您的视图代码中,您可以通过为其指定新的日期格式来格式化任何日期:

My Date: <%= h some_date.to_s(:my_date) %>
Run Code Online (Sandbox Code Playgroud)

它很简单,很有效,并且易于构建.只需在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}") }
)
Run Code Online (Sandbox Code Playgroud)

  • 很好的答案.对于Rails 3,ActiveSupport已经发生了很大的变化,所以以下是等价的:`Time :: DATE_FORMATS.merge!(:my_date => lambda {| time | time.strftime("%a,%b#{ActiveSupport: :Inflector.ordinalize(time.day)}")})` (7认同)

Jim*_*nti 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"
Run Code Online (Sandbox Code Playgroud)


Oli*_*can 7

虽然 Jonathan Tran 确实说过他首先要查找星期几的缩写,然后是月份的缩写,但我认为对于最终来到这里的人来说,知道 Rails 对更多内容具有开箱即用的支持可能会很有用。通常使用长月份、有序日整数,后跟年份,如 中所示June 1st, 2018

它可以通过以下方式轻松实现:

Time.current.to_date.to_s(:long_ordinal)
=> "January 26th, 2019"
Run Code Online (Sandbox Code Playgroud)

或者:

Date.current.to_s(:long_ordinal)
=> "January 26th, 2019"
Run Code Online (Sandbox Code Playgroud)

如果您愿意,也可以坚持使用时间实例:

Time.current.to_s(:long_ordinal)
=> "January 26th, 2019 04:21"
Run Code Online (Sandbox Code Playgroud)

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


Pat*_*zie 6

我喜欢Bartosz的答案,但是,嘿,因为这是我们正在谈论的Rails,让我们在狡猾中采取一步.(编辑:虽然我打算使用以下方法进行monkeypatch,但事实证明有一种更清洁的方法.)

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

这些符号由定义Time::DATE_FORMATS,它是标准格式化函数...或procs的字符串的符号散列.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
Run Code Online (Sandbox Code Playgroud)

但是,嘿,如果你无法抗拒monkeypatch的机会,你总能给出一个更清晰的界面:

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
Run Code Online (Sandbox Code Playgroud)


Jos*_*ter 6

创建您自己的%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 }
Run Code Online (Sandbox Code Playgroud)

用法

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

您也可以将其与Date和一起使用DateTime

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

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

  • @kcdragon 哇,你说得完全正确。搜索代码库,发现我的老朋友 Chuck Bergeron 在大约 7 年前添加了这个初始化程序。无论如何,我仍然发现这非常有用,因此我更新了答案,说明如何实现它,就像我们在 CNTRAL 中一样。 (3认同)
  • 我无法让它在 2.6.3 上运行。也许是旧版本的 Ruby 中的?或者也许有人在你的项目中修补了“Time”? (2认同)