web-dev-qa-db-fra.com

Dans Ruby on Rails, comment formater une date avec le suffixe "e", comme dans "Sun Oct 5"?

Je souhaite afficher les dates dans le format: jour court, mois court, jour du mois sans zéro mais avec suffixe "e", "st", "nd" ou "rd".

Par exemple, le jour où cette question a été posée affichera "Jeu 2 octobre".

J'utilise Ruby 1.8.7, et Time.strftime ne semble pas le faire. Je préférerais une bibliothèque standard s'il en existe une.

168
Jonathan Tran

Utilisez la méthode ordinalize de 'active_support'.

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

Notez que si vous utilisez IRB avec Ruby 2.0, vous devez d’abord exécuter:

require 'active_support/core_ext/integer/inflections'
266
Bartosz Blimke

Vous pouvez utiliser la méthode d'assistance ordinalize de active_support sur les nombres. 

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

Prenant la réponse de Patrick McKenzie un peu plus loin, vous pouvez créer un nouveau fichier dans votre répertoire config/initializers appelé date_format.rb (ou ce que vous voulez) et y insérer ceci:

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

Ensuite, dans votre code d'affichage, vous pouvez formater n'importe quelle date simplement en lui attribuant votre nouveau format de date:

My Date: <%= h some_date.to_s(:my_date) %>

C'est simple, ça marche et c'est facile à construire. Ajoutez simplement plus de lignes de format dans le fichier date_format.rb pour chacun de vos différents formats de date. Voici un exemple plus complet.

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}") }
)
29
Richard Hurt
>> require 'activesupport'
=> []
>> t = Time.now
=> Thu Oct 02 17:28:37 -0700 2008
>> formatted = "#{t.strftime("%a %b")} #{t.day.ordinalize}"
=> "Thu Oct 2nd"
9
Jimmy Schementi

J'aime la réponse de Bartosz, mais bon, puisque c'est de Rails que nous parlons, prenons un pas de plus sournois. (Edit: Bien que j'allais juste monkeypatch la méthode suivante, il s'avère qu'il y a une manière plus propre.)

Les instances DateTime ont une méthode to_formatted_s fournie par ActiveSupport, qui prend un symbole unique en tant que paramètre et, si ce symbole est reconnu comme format prédéfini valide, renvoie une chaîne avec le formatage approprié. 

Ces symboles sont définis par Time::DATE_FORMATS, qui est un hachage de symboles en chaînes pour la fonction de formatage standard ... ou 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

Mais bon, si vous ne pouvez pas résister à l’opportunité de jouer avec monkeypatch, vous pouvez toujours lui donner une interface plus propre:

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
Patrick McKenzie

Utilisez %o.

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

Attention: Vous ne pouvez pas utiliser ceci avec DateTime:

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

Mais vous devriez quand même utiliser Time et c’est une bonne raison de changer.

2
Joshua Pinter

Bien que Jonathan Tran ait déclaré qu'il recherchait le jour abrégé de la semaine suivi du mois abrégé, je pense qu'il serait peut-être utile que les personnes qui se rendent ici sachent que Rails dispose d'une assistance immédiate mois long communément utilisé, jour entier ordiné, suivi de l’année, comme dans June 1st, 2018.

Il peut être facilement réalisé avec:

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

Ou:

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

Vous pouvez également vous en tenir à une instance temporelle:

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

Vous pouvez trouver plus de formats et de contextes sur la façon de créer un format personnalisé dans Rails API docs .

1
Olivier Lacan