【问题标题】:In Ruby on Rails, how do I format a date with the "th" suffix, as in, "Sun Oct 5th"?在 Ruby on Rails 中,如何格式化带有“th”后缀的日期,例如“Sun Oct 5th”?
【发布时间】:2010-09-14 23:26:15
【问题描述】:

我想以以下格式显示日期:短星期几、短月份、不带前导零但包括“th”、“st”、“nd”或“rd”后缀的月份。

例如,提出此问题的日期将显示“Thu Oct 2nd”。

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

【问题讨论】:

  • 您可能希望在您的问题或标题中使用“后缀”一词,以便其他人更容易找到它。我不确定在谈论日期时是否还有其他词。
  • 很好的问题。几天前我还在想同样的事情 - 非常有帮助。

标签: ruby-on-rails ruby date


【解决方案1】:

使用 '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'

【讨论】:

  • 请注意这不在标准库中。
【解决方案2】:

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

>> 3.ordinalize
=> "3rd"
>> 2.ordinalize
=> "2nd"
>> 1.ordinalize
=> "1st"

【讨论】:

  • 现在是 2020 年,但仍然是这样的事情让我爱上了 Rails。
【解决方案3】:

进一步了解 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}") }
)

【讨论】:

  • 不错的答案。对于 Rails 3,ActiveSupport 发生了很大的变化,所以下面是等效的:Time::DATE_FORMATS.merge!(:my_date =&gt; lambda { |time| time.strftime("%a, %b #{ActiveSupport::Inflector.ordinalize(time.day)}") })
  • 爱上 Rails :)
【解决方案4】:
>> 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】:

    我喜欢 Bartosz 的回答,但是,嘿,既然这是我们正在谈论的 Rails,让我们在迂回的过程中更上一层楼。 (编辑:虽然我打算只对以下方法进行monkeypatch,但事实证明有一种更清洁的方法。)

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

    这些符号由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
    

    【讨论】:

      【解决方案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 }
      

      用法

      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"
      

      【讨论】:

      • 不确定这是否记录在案。我似乎找不到它的任何记录,但我们在代码库中使用它,所以一定是在某个地方找到它。
      • 我无法让它在 2.6.3 上运行。也许它是在旧版本的 Ruby 中?或者也许有人在你的项目中修补了Time
      • @kcdragon 哇,你完全正确。搜索代码库,发现我的老朋友 Chuck Bergeron 在将近 7 年前添加了这个初始化器。无论如何,我仍然觉得这非常有用,所以我更新了答案,说明如何实现它,就像我们在 CNTRAL 中一样。
      • 这些 cmets 太搞笑了!
      【解决方案7】:

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

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

      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 docs 中找到有关如何创建自定义格式的更多格式和上下文。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-09
        • 1970-01-01
        • 1970-01-01
        • 2011-01-30
        • 2016-01-08
        相关资源
        最近更新 更多