Formatieren Sie das Datum mit Ruby on Rails

74

Die flickr-API liefert ein Datum als Unix-Zeitstempel: " The posted date is always passed around as a unix timestamp, which is an unsigned integer specifying the number of seconds since Jan 1st 1970 GMT."

Hier ist zum Beispiel das Datum ' 1100897479'. Wie formatiere ich es mit Ruby on Rails?

Alexandre
quelle

Antworten:

190

Nachdem Sie die Zeitstempelzeichenfolge analysiert und ein Zeitobjekt erstellt haben (Einzelheiten finden Sie in den anderen Antworten), können Sie Time.to_formatted_s von Rails verwenden. Es sind mehrere Formate integriert, die Sie mit Symbolen angeben können.

Zitat:

time = Time.now                     # => Thu Jan 18 06:10:17 CST 2007

time.to_formatted_s(:time)          # => "06:10"
time.to_s(:time)                    # => "06:10"

time.to_formatted_s(:db)            # => "2007-01-18 06:10:17"
time.to_formatted_s(:number)        # => "20070118061017"
time.to_formatted_s(:short)         # => "18 Jan 06:10"
time.to_formatted_s(:long)          # => "January 18, 2007 06:10"
time.to_formatted_s(:long_ordinal)  # => "January 18th, 2007 06:10"
time.to_formatted_s(:rfc822)        # => "Thu, 18 Jan 2007 06:10:17 -0600"

(Time.to_s ist ein Alias)

Sie können auch Ihre eigenen Formate definieren - normalerweise in einem Initialisierer (Dank an Dave Newton für diesen Hinweis). So wird's gemacht:

# config/initializers/time_formats.rb
Time::DATE_FORMATS[:month_and_year] = "%B %Y"
Time::DATE_FORMATS[:short_ordinal] = lambda { |time| time.strftime("%B #{time.day.ordinalize}") }
CMW
quelle
+1; Die einfachste Lösung, sobald ein Datum vorliegt, insbesondere wenn eines der vorhandenen Formate funktioniert.
Dave Newton
4
Ja, über eine Karte in Initialisierern.
Dave Newton
3
Beachten Sie, dass Time :: DATE_FORMATS nicht an Rails-Date-Objekte weitergeleitet wird. Für Date-Objekte verwenden Sie Date :: DATE_FORMATS
ReggieB
Sie können jetzt auch I18n verwenden. guides.rubyonrails.org/i18n.html#adding-date-time-formats
PhilT
Wenn eine Sprache von einem japanischen Entwickler geschrieben wird, ist es kein Wunder, dass die Daten so nicht US-freundlich sind :)
Kuf
46

Hier ist meine Antwort darauf:

Daher müssen Sie zuerst den Zeitstempel in ein tatsächliches Ruby-Datum / eine aktuelle Ruby-Uhrzeit konvertieren. Wenn Sie es nur als String oder Int von Facebook erhalten, müssen Sie Folgendes tun:

my_date = Time.at(timestamp_from_facebook.to_i)

OK, jetzt vorausgesetzt, Sie haben bereits Ihr Datumsobjekt ...

to_formatted_s ist eine praktische Ruby-Funktion, die Datumsangaben in formatierte Zeichenfolgen umwandelt .

Hier sind einige Beispiele für seine Verwendung:

time = Time.now                     # => Thu Jan 18 06:10:17 CST 2007    

time.to_formatted_s(:time)          # => "06:10"
time.to_s(:time)                    # => "06:10"    

time.to_formatted_s(:db)            # => "2007-01-18 06:10:17"
time.to_formatted_s(:number)        # => "20070118061017"
time.to_formatted_s(:short)         # => "18 Jan 06:10"
time.to_formatted_s(:long)          # => "January 18, 2007 06:10"
time.to_formatted_s(:long_ordinal)  # => "January 18th, 2007 06:10"
time.to_formatted_s(:rfc822)        # => "Thu, 18 Jan 2007 06:10:17 -0600"

Wie Sie sehen können :: db ,: number ,: short ... sind benutzerdefinierte Datumsformate.

Um Ihr eigenes benutzerdefiniertes Format hinzuzufügen, können Sie diese Datei erstellen: config / initializers / time_formats.rb und dort Ihre eigenen Formate hinzufügen, zum Beispiel eines:

Date::DATE_FORMATS[:month_day_comma_year] = "%B %e, %Y" # January 28, 2015

Wobei : month_day_comma_year der Name Ihres Formats ist (Sie können dies in einen beliebigen Namen ändern) und wobei % B% e,% Y das Unix-Datumsformat ist.

Hier ist ein kurzes Cheatsheet zur Unix-Datumssyntax, damit Sie Ihr benutzerdefiniertes Format schnell einrichten können:

From http://linux.die.net/man/3/strftime    

  %a - The abbreviated weekday name (``Sun'')
  %A - The  full  weekday  name (``Sunday'')
  %b - The abbreviated month name (``Jan'')
  %B - The  full  month  name (``January'')
  %c - The preferred local date and time representation
  %d - Day of the month (01..31)
  %e - Day of the month without leading 0 (1..31) 
  %g - Year in YY (00-99)
  %H - Hour of the day, 24-hour clock (00..23)
  %I - Hour of the day, 12-hour clock (01..12)
  %j - Day of the year (001..366)
  %m - Month of the year (01..12)
  %M - Minute of the hour (00..59)
  %p - Meridian indicator (``AM''  or  ``PM'')
  %S - Second of the minute (00..60)
  %U - Week  number  of the current year,
          starting with the first Sunday as the first
          day of the first week (00..53)
  %W - Week  number  of the current year,
          starting with the first Monday as the first
          day of the first week (00..53)
  %w - Day of the week (Sunday is 0, 0..6)
  %x - Preferred representation for the date alone, no time
  %X - Preferred representation for the time alone, no date
  %y - Year without a century (00..99)
  %Y - Year with century
  %Z - Time zone name
  %% - Literal ``%'' character    

   t = Time.now
   t.strftime("Printed on %m/%d/%Y")   #=> "Printed on 04/09/2003"
   t.strftime("at %I:%M%p")            #=> "at 08:56AM"

Hoffe das hat dir geholfen. Ich habe auch einen Github-Kern dieses kleinen Leitfadens gemacht, falls jemand es vorzieht.

Edu Wass
quelle
Während dieser Link die Frage beantworten kann, ist es besser, die wesentlichen Teile der Antwort hier aufzunehmen und den Link als Referenz bereitzustellen. Nur-Link-Antworten können ungültig werden, wenn sich die verknüpfte Seite ändert. - Aus der Bewertung
Mihai Caracostea
Hallo @MihaiCaracostea, habe meine Antwort auf Ihren Rat wiederholt, danke :)
Edu Wass
1
Funktioniert es nicht bei mir? Ich habe das Datumsformat im Initialisierungsordner hinzugefügt. Hier ist, wie @question.created_at.to_formatted_s(:month_day_comma_year)ich es in der Ansicht benutze, aber ich bekomme#2019-07-27 03:27:41 UTC
Steven Aguilar
Was ist mit DateTimekann es auch verwenden?
Steven Aguilar
27

Am einfachsten ist es, strftime(docs) zu verwenden .

Wenn es auf der Ansichtsseite verwendet werden soll, ist es jedoch besser, es in einen Helfer zu wickeln.

Dave Newton
quelle
1
Ich habe nicht herausgefunden, wie ich es benutzen soll. Können Sie mir bitte ein kleines Beispiel geben?
Alexandre
6
my_date_variable.strftime ("% m /% d /% Y")
aldo.roman.nurena
7
Die Zeit ist nicht trocken. Bitte verteilen Sie keine Zeit auf Ihre Projekte. Zumindest haben Sie einen Helfer erwähnt, der config/initializers/time_formats.rbfür Rails jedoch idiomatischer ist.
PhilT
@PhilT Wie ich in meinem Kommentar zur am höchsten bewerteten Antwort erwähnt habe, wurde diese Antwort berücksichtigt.
Dave Newton
17

@ CMWs Antwort ist knallhart. Ich habe diese Antwort als Beispiel für die Konfiguration eines Initialisierers hinzugefügt, damit sowohl Datums- als auch Zeitobjekte die Formatierung erhalten

config / initializers / time_formats.rb

date_formats = {
  concise: '%d-%b-%Y' # 13-Jan-2014
}

Time::DATE_FORMATS.merge! date_formats
Date::DATE_FORMATS.merge! date_formats

Die folgenden beiden Befehle durchlaufen alle DATE_FORMATSin Ihrer aktuellen Umgebung und zeigen das heutige Datum und die Uhrzeit in jedem Format an:

Date::DATE_FORMATS.keys.each{|k| puts [k,Date.today.to_s(k)].join(':- ')}
Time::DATE_FORMATS.keys.each{|k| puts [k,Time.now.to_s(k)].join(':- ')}
ReggieB
quelle
6

Zuerst müssen Sie den Zeitstempel in ein tatsächliches Ruby-Datum / eine aktuelle Ruby-Uhrzeit konvertieren. Wenn Sie es nur als String oder Int von Facebook erhalten, müssen Sie Folgendes tun:

my_date = Time.at(timestamp_from_facebook.to_i)

Um es dann in der Ansicht schön zu formatieren, können Sie es einfach verwenden to_s(für die Standardformatierung):

<%= my_date.to_s %>

Wenn Sie dies nicht tun, to_swird es standardmäßig weiterhin aufgerufen, wenn Sie es in einer Ansicht oder in einer Zeichenfolge verwenden, z. B. wird to_sam Datum auch Folgendes aufgerufen :

<%= "Here is a date: #{my_date}" %>

oder wenn Sie möchten, dass das Datum auf eine bestimmte Weise formatiert wird (z. B. mit "d / m / Y"), können Sie es strftimewie in der anderen Antwort beschrieben verwenden.

Taryn East
quelle
Dieser Code löst einen Fehler aus puts Time.at('1100897479')- String kann nicht in eine exakte Zahl konvertiert werden (TypeError)
Alexandre
Ah, es kommt als Schnur an? ok also "to_i" es, um sicherzustellen, dass es ein int ist (Beispiel oben bearbeitet, um dies einzuschließen)
Taryn East
1

Da die Zeitstempel seit der UNIX-Epoche Sekunden sind, können Sie DateTime.strptime ("String- Analysezeit ") mit dem richtigen Bezeichner verwenden :

Date.strptime('1100897479', '%s')
#=> #<Date: 2004-11-19 ((2453329j,0s,0n),+0s,2299161j)>
Date.strptime('1100897479', '%s').to_s
#=> "2004-11-19"
DateTime.strptime('1100897479', '%s')
#=> #<DateTime: 2004-11-19T20:51:19+00:00 ((2453329j,75079s,0n),+0s,2299161j)>
DateTime.strptime('1100897479', '%s').to_s
#=> "2004-11-19T20:51:19+00:00"

Beachten Sie, dass Sie dies tun müssen require 'date', damit dies funktioniert. Sie können es entweder als Date.strptime(wenn Sie sich nur um das Datum kümmern) oder DateTime.strptime(wenn Sie Datum und Uhrzeit möchten ) aufrufen . Wenn Sie eine andere Formatierung benötigen, können Sie DateTime # strftime (siehe strftime.net, wenn Sie Schwierigkeiten mit den Formatierungszeichenfolgen haben) aufrufen oder eine der integrierten Methoden wie verwenden rfc822.

Michael Kohl
quelle