Wie konvertiert man einen Unix-Zeitstempel (Sekunden seit der Epoche) in Ruby DateTime?
369
DateTime.strptime
kann Sekunden seit der Epoche verarbeiten. Die Nummer muss in eine Zeichenfolge konvertiert werden:
require 'date'
DateTime.strptime("1318996912",'%s')
%Q
tho.Time
es notwendig stattDateTime
. VerwendenTime.strptime("1318996912345",'%Q').to_f
Sie also und Sie werden sehen, dass die Millisekunden erhalten bleiben, währendDateTime.strptime("1318996912345",'%Q').to_f
sie nicht erhalten bleiben.Entschuldigung, kurzer Moment des Synapsenversagens. Hier ist die wahre Antwort.
Kurzes Beispiel (dies berücksichtigt die aktuelle Systemzeitzone):
Weiteres Update (für UTC):
Letztes Update : Ich habe die Top-Lösungen in diesem Thread vor ein oder zwei Wochen bei der Arbeit an einem HA-Service verglichen und war überrascht, dass diese
Time.at(..)
Outperformance erzielt wurdeDateTime.strptime(..)
(Update: Weitere Benchmarks hinzugefügt).quelle
Time.at
besser abschneidetDateTime.strptime
. Letzterer muss eine Zeichenfolge analysieren, die im Allgemeinen viel langsamer ist als die direkte Eingabe einer Zahl.DateTime.strptime
da bei jeder Iteration zwei neue Strings erstellt werden, was sehr teuer ist. Es ist nicht nur das Parsen von Strings, wie @claw sagteZeitzonenbehandlung
Ich möchte nur klarstellen, obwohl dies kommentiert wurde, damit zukünftige Leute diese sehr wichtige Unterscheidung nicht verpassen.
Zeigt einen Rückgabewert in UTC an und erfordert, dass die Sekunden ein String sind, und gibt ein UTC-Zeitobjekt aus
Zeigt einen Rückgabewert in der LOCAL-Zeitzone an, erfordert normalerweise ein FixNum-Argument, aber das Time-Objekt selbst befindet sich immer noch in UTC, obwohl die Anzeige dies nicht ist.
Obwohl ich beiden Methoden dieselbe Ganzzahl übergeben habe, habe ich aufgrund der Funktionsweise der Klassenmethode anscheinend zwei unterschiedliche Ergebnisse erzielt
#to_s
. Da @Eero mich jedoch zweimal daran erinnern musste:Ein Gleichheitsvergleich zwischen den beiden Rückgabewerten gibt weiterhin true zurück. Dies liegt wiederum daran, dass die Werte im Grunde genommen gleich sind (obwohl verschiedene Klassen, die
#==
Methode kümmert sich für Sie darum), aber die#to_s
Methode druckt drastisch unterschiedliche Zeichenfolgen. Wenn wir uns die Zeichenfolgen ansehen, können wir jedoch feststellen, dass sie tatsächlich dieselbe Zeit sind und nur in verschiedenen Zeitzonen gedruckt werden.Klärung des Methodenarguments
In den Dokumenten heißt es außerdem: "Wenn ein numerisches Argument angegeben wird, ist das Ergebnis in Ortszeit." Das macht Sinn, war aber für mich etwas verwirrend, weil sie in den Dokumenten keine Beispiele für nicht ganzzahlige Argumente enthalten. Für einige Beispiele für nicht ganzzahlige Argumente:
Sie können kein String-Argument verwenden, aber Sie können ein Time-Argument in verwenden,
Time.at
und das Ergebnis wird in der Zeitzone des Arguments zurückgegeben:Benchmarks
Nach einer Diskussion mit @AdamEberlin über seine Antwort habe ich beschlossen, leicht geänderte Benchmarks zu veröffentlichen, um alles so gleich wie möglich zu machen. Außerdem möchte ich diese nie wieder bauen müssen, damit dies so gut wie jeder andere Ort ist, um sie zu retten.
Time.at (int) .to_datetime ~ 2.8x schneller
**** bearbeitet, um nicht in jeder Hinsicht vollständig und völlig falsch zu sein ****
**** Benchmarks hinzugefügt ****
quelle
Time.at(1318996912) == DateTime.strptime("1318996912",'%s')
in einer Nicht-UTC-Zeitzone und Sie werden sehen!Time.use_zone "Samoa" do Time.at(1318996912) == DateTime.strptime("1318996912",'%s') end
, um sicherzustellen , dass die Zeiten gleich sind. Es gibt keinen lokalen Zeitstempel. In beiden Fällen wird der Unix-Zeitstempel als UTC interpretiert.Time.at
präsentiert das resultierende Zeitobjekt in der lokalen Zeitzone, undDateTime.strptime
präsentiert das resultierende Datetime - Objekt in UTC, aber unabhängig davon , Präsentation sie gleich sind, da sie der entsprechende Zeitpunkt ist.Time.at(1318996912) # => 2011-10-19 00:01:52 -0400
ein Rückgabewert in der lokalen Zeitzone angezeigt wird, scheint nicht korrekt zu sein ... Können Sie dies bitte überprüfen? Ich glaube, Ihre Aussage wäre nur wahr, wenn SieTime.zone.at(1318996912)
Ein Befehl zum Konvertieren der Datums- und Uhrzeit in das Unix-Format und anschließend in eine Zeichenfolge
Schließlich wird strftime zum Formatieren des Datums verwendet
Beispiel:
quelle
Time.now.utc.to_i
.Hier erfahren Sie das Datum der Anzahl der Sekunden in der Zukunft ab dem Zeitpunkt, an dem Sie den Code ausführen.
setzt (Zeit)
Nach der aktuellen Zeit beantworte ich die Frage, die gedruckt wird
047-05-14 05:16:16 +0000
(1 Milliarde Sekunden in der Zukunft).oder wenn Sie Milliarden Sekunden ab einer bestimmten Zeit zählen möchten, ist es im Format
Time.mktime(year, month,date,hours,minutes)
setzt ("Ich wäre 1 Milliarde Sekunden alt auf:" + Zeit)
quelle
Wenn Sie nur ein Datum möchten, können Sie tun,
Date.strptime(invoice.date.to_s, '%s')
wo esinvoice.date
in Form einesFixnum
und dann in ein konvertiert wirdString
.quelle
Time.at(1500923406).to_date.to_s
=>"2017-07-24"