В Ruby on Rails, как мне отформатировать дату с суффиксом th, как в «Sun Oct 5th»? - PullRequest
171 голосов
/ 03 октября 2008

Я хочу отображать даты в формате: короткий день недели, короткий месяц, день месяца без начального нуля, но с суффиксом th, st, nd или rd.

Например, день, когда этот вопрос был задан, будет отображать «Чт 2 октября».

Я использую Ruby 1.8.7, а Time.strftime , похоже, не делает этого. Я бы предпочел стандартную библиотеку, если она существует.

Ответы [ 7 ]

270 голосов
/ 03 октября 2008

Используйте метод ординализации из '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'
93 голосов
/ 03 октября 2008

Вы можете использовать метод вспомогательных функций active_support для чисел.

>> 3.ordinalize
=> "3rd"
>> 2.ordinalize
=> "2nd"
>> 1.ordinalize
=> "1st"
29 голосов
/ 11 января 2009

Взяв ответ Патрика МакКензи чуть дальше, вы можете создать новый файл в вашей директории 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}") }
)
9 голосов
/ 03 октября 2008
>> require 'activesupport'
=> []
>> t = Time.now
=> Thu Oct 02 17:28:37 -0700 2008
>> formatted = "#{t.strftime("%a %b")} #{t.day.ordinalize}"
=> "Thu Oct 2nd"
6 голосов
/ 03 октября 2008

Мне нравится ответ Бартоша, но, эй, так как это Rails, о котором мы говорим, давайте сделаем один шаг вперед в хитрости. (Правка: хотя я собирался просто обезьянить следующий метод, оказывается, есть более чистый способ.)

DateTime экземпляры имеют метод to_formatted_s, предоставленный ActiveSupport, который принимает один символ в качестве параметра и, если этот символ распознается как допустимый предопределенный формат, возвращает строку с соответствующим форматированием.

Эти символы определены как Time::DATE_FORMATS, который представляет собой хэш символов либо для строк стандартной функции форматирования ..., либо для процедур. 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

Но, эй, если вы не можете устоять перед возможностью получить 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
2 голосов
/ 20 октября 2018

Использование %o.

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

Осторожно: Вы не можете использовать это с DateTime:

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

Но вы все равно должны использовать Time, и это хорошая причина для переключения.

1 голос
/ 26 января 2019

Хотя Джонатан Тран и сказал, что сначала он искал сокращенный день недели, а затем сокращенный месяц, я думаю, что людям, которые в конечном итоге оказываются здесь, было бы полезно узнать, что 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 документах .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...