ใน Ruby on Rails ฉันจะจัดรูปแบบวันที่ด้วยคำต่อท้าย“ th” เช่นเดียวกับใน“ Sun Oct 5th” ได้อย่างไร


177

ฉันต้องการแสดงวันที่ในรูปแบบ: วันสั้น ๆ ของสัปดาห์, เดือนสั้น, วันที่ไม่มีศูนย์นำหน้า แต่รวมถึง "th", "st", "nd", หรือคำต่อท้าย "rd"

ตัวอย่างเช่นวันที่ถามคำถามนี้จะแสดง "Thu Oct 2"

ฉันใช้ Ruby 1.8.7 และTime.strimeเพียงดูเหมือนจะไม่ทำเช่นนี้ ฉันต้องการห้องสมุดมาตรฐานถ้ามีอยู่


2
คุณอาจต้องการใช้คำว่า "คำต่อท้าย" ในคำถามหรือชื่อของคุณเพื่อให้คนอื่นค้นพบได้ง่ายขึ้น ฉันไม่แน่ใจว่ามีคำอื่นสำหรับเรื่องนี้เมื่อพูดถึงวันที่
Harley Holcombe

คำถามที่ยอดเยี่ยม ฉันคิดในสิ่งเดียวกันเมื่อสองสามวันก่อน - มีประโยชน์มาก
RichH

คำตอบ:


278

ใช้วิธีจัดลำดับจาก 'active_support'

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

15
เพิ่งทราบว่านี่ไม่ได้อยู่ในห้องสมุดมาตรฐาน
Chris Lloyd

97

คุณสามารถใช้วิธีการจัดอันดับผู้ช่วย active_support ของตัวเลข

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

30

นำคำตอบของ 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}") }
)

7
คำตอบที่ดี สำหรับ Rails 3 นั้น ActiveSupport เปลี่ยนไปเล็กน้อยดังนั้นสิ่งต่อไปนี้จะเทียบเท่า:Time::DATE_FORMATS.merge!(:my_date => lambda { |time| time.strftime("%a, %b #{ActiveSupport::Inflector.ordinalize(time.day)}") })
Sidane


6

ฉันชอบคำตอบของ Bartosz แต่เดี๋ยวก่อนเพราะนี่คือ Rails ที่เรากำลังพูดถึงกันเถอะเอาขั้นตอนหนึ่งขึ้นมาอย่างคดเคี้ยว (แก้ไข: แม้ว่าฉันจะเพียงแค่ลิงวิธีการดังต่อไปนี้กลับกลายเป็นว่ามีวิธีที่สะอาดขึ้น)

DateTimeอินสแตนซ์มีto_formatted_sวิธีการที่จัดทำโดย ActiveSupport ซึ่งใช้สัญลักษณ์เดียวเป็นพารามิเตอร์และหากสัญลักษณ์นั้นได้รับการยอมรับว่าเป็นรูปแบบที่กำหนดไว้ล่วงหน้าที่ถูกต้องจะส่งคืนสตริงด้วยการจัดรูปแบบที่เหมาะสม

สัญลักษณ์เหล่านั้นถูกกำหนดโดย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

แต่เดี๋ยวก่อนถ้าคุณไม่สามารถต้านทานโอกาสที่จะลิงได้คุณสามารถให้อินเทอร์เฟซที่สะอาดกว่าได้เสมอ:

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

3

สร้างของคุณเอง %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"

คุณสามารถใช้กับ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"

ไม่แน่ใจว่าเป็นเอกสารหรือไม่ ฉันดูเหมือนจะไม่พบบันทึกใด ๆ ของมัน แต่เราใช้มันในฐานรหัสของเราดังนั้นจะต้องพบมันที่ไหนสักแห่ง
Joshua Pinter

1
ฉันไม่สามารถทำให้มันใช้งานได้ใน 2.6.3 อาจเป็นทับทิมรุ่นเก่ากว่าไหม หรืออาจมีบางคนกำลังติดปะติดลิงTimeในโครงการของคุณ?
kcdragon

2
@kcdragon ว้าวคุณพูดถูกแล้ว ค้นหา codebase และพบว่าเพื่อนเก่าของฉัน Chuck Bergeron เพิ่มตัวเริ่มต้นนี้เกือบ 7 ปีที่แล้ว ไม่ว่าฉันยังคงพบว่ามีประโยชน์มากดังนั้นฉันจึงได้อัปเดตคำตอบพร้อมกับนำไปใช้อย่างที่เรามีใน CNTRAL
Joshua Pinter

2

ถึงแม้ว่า 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 เอกสาร

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.