Wie erhalte ich die aktuelle Zeit als 13-stellige Ganzzahl in Ruby?

87

Ich habe diese jQueryFunktion, die die aktuelle Zeit als Anzahl der Millisekunden seit der Epoche (1. Januar 1970) zurückgibt:

time = new Date().getTime();

Gibt es eine Möglichkeit, dies auch in Ruby zu tun?

Im Moment verwende ich Ruby's, Time.now.to_idas hervorragend funktioniert, aber eine 10-stellige Ganzzahl (Anzahl der Sekunden) zurückgibt.

Wie kann ich die Anzahl der Millisekunden wie in anzeigen lassen jQuery?

Tim und Struppi81
quelle
4
Das ist keine "jQuery-Funktion", sondern nur einfaches ECMAScript (Javascript). Vielleicht hat das den -1 veranlasst, allerdings etwas hart.
RobG
Siehe auch stackoverflow.com/q/20001883/238886
Wayne Conrad

Antworten:

151
require 'date'

p DateTime.now.strftime('%s') # "1384526946" (seconds)
p DateTime.now.strftime('%Q') # "1384526946523" (milliseconds)
steenslag
quelle
31
Hinweis für Rails-Benutzer: Die von strftimebereitgestellte Methode ActiveSupport::TimeWithZoneenthält nicht die Bezeichner %sund %Q. Sie müssen DateTimezuerst mithilfe der to_datetimeMethode in einen einfachen Ruby konvertieren .
Lonnon Foster
5
@LonnonFoster Jetzt funktioniert es (gerade in der Rails-Konsole getestet).
Nikola Stojaković
Hallo, wie kann ich das Gleiche tun, aber nicht für den Moment, sondern von einem Datumsfeld aus?
Tomer
99

Javascript gettime()gibt die Anzahl der Millisekunden seit der Epoche zurück.

Ruby's Time.now.to_igibt Ihnen die Anzahl der Sekunden seit der Epoche. Wenn Sie dies ändern Time.now.to_f, erhalten Sie immer noch Sekunden, jedoch mit einer Bruchkomponente. Multiplizieren Sie das einfach mit 1.000 und Sie haben Millisekunden. Verwenden Sie dann #to_i, um es in eine Ganzzahl zu konvertieren. Und am Ende haben Sie:

(Time.now.to_f * 1000).to_i
Anthony DeSimone
quelle
Vielen Dank für die Erklärung! Noch neu in dieser ganzen Sache ... Ich weiß nicht, welche Antwort ich eigentlich als die richtige markieren soll ...
Tim und Struppi81
1
Nur für weitere Informationen, Time.nowkommt von Ruby da Time.currentkommt von Rails. Dies Time.currentwird von der Rails-Anwendungszeitzone bestätigt und Time.nowverwendet die Serverzeitzone. Nach meiner Erfahrung verwenden Sie immer Time.currentauf Ihrer Rails-Anwendung für Zeitzonenkonsistenz
Vutran
1
Nein, Sie sollten Time.currenthier überhaupt nicht verwenden , das Erstellen dauert länger. Da Sie es sofort in einen Unix-Zeitstempel konvertieren, ist Ihnen die Zeitzonenkonsistenz überhaupt egal. (Unix-Zeitstempel beziehen sich immer auf UTC). Während das, was Sie sagen, in 99% der Fälle zutrifft, fällt dieses in Bezug auf die Leistung in die letzten 1%.
Der Pellmeister
1
Dies ist mein bevorzugter Ansatz. Eine Sache, die ich gerne mache, ist, die Time-Klasse zu erweitern, um eine :epochMethode hinzuzufügen : class Time def epoch (self.to_f * 1000) .to_i end end
Matt Welke
1
Dies fälscht die Millisekunden
Brauliobo
28

(Time.now.to_f * 1000).to_i sollte das gleiche tun.

Zach Kemp
quelle
1
@ Brauliobo Was ist gefälschte Millisekunden?
Erik Rothoff
1
@brauliobo Dies ist nicht der Fall, da to_fMillisekunden als Dezimalzahl enthalten sind.
CashIsClay
19

Mit strftimekönnen Sie die Anzahl der Sekunden ermitteln und Millisekunden (oder bei Bedarf kleinere Einheiten) anhängen:

2.2.2 :001 > t = Time.new
 => 2015-06-02 12:16:56 -0700 
2.2.2 :002 > t.strftime('%s%3N')
 => "1433272616888" 

Beachten Sie jedoch, dass dies nicht rund ist, sondern abgeschnitten wird, wie Sie sehen können to_foder wenn Sie auf Mikrosekunden gehen:

2.2.2 :003 > t.to_f
 => 1433272616.888615
2.2.2 :004 > t.usec
 => 888615 

und die to_f/ to_iLösung hat das gleiche Problem:

2.2.2 :009 > (t.to_f * 1000).to_i
 => 1433272616888

Wenn Sie also wirklich um Millisekunden Genauigkeit sorgen, eine bessere Wette sein kann to_fmit round:

2.2.2 :010 > (t.to_f * 1000).round
 => 1433272616889

Wie in den Dokumenten erwähnt , ist "IEEE 754 double nicht genau genug, um die Anzahl der Nanosekunden seit der Epoche darzustellen". Wenn Sie sich also wirklich wirklich darum kümmern, sollten Sie to_rstatt to_f-

2.2.2 :011 > (t.to_r * 1000).round
 => 1433272616889 

- obwohl es Ihnen wahrscheinlich gut geht, wenn Sie nur auf Millisekunden runden.

David Moles
quelle
18

Sei vorsichtig, sei nicht verwirrt. Die Tatsache, dass Ruby die Idee von Sekundenbruchteilen als Gleitkomma unterstützt, macht es nicht zu einer Gleitkommazahl. Ich hatte Probleme damit, als ich Wireshark-Zeitstempel-Zeitvergleiche in Python durchführte ... die Zeitberechnungen im pcap-ng funktionierten einfach nicht. Erst als ich die beiden Teile (integrale Sekunden und integrale Nanosekunden) als beide ganzen Zahlen behandelte, konnte ich die richtigen Zahlen erhalten.

Dies liegt daran, dass Gleitkommazahlen Genauigkeitsprobleme haben . In der Tat zeigt Ihnen ein kurzes Stück Ruby, dass to_f nicht gleich nsec ist:

irb(main):019:0> t=Time.now
=> 2015-04-10 16:41:35 -0500
irb(main):020:0> puts "#{t.to_f}; #{t.nsec}"
1428702095.1435847; 143584844

Vorsichtsmaßnahme Programmierer. Sie können bis zu 3 signifikanten Stellen sicher sein, aber die Tatsache bleibt: Gleitkommazahlen auf Computern sind Näherungswerte. Die Nanosekundenzähler auf modernen Computern sind ganze Zahlen.

Mike S.
quelle
Die bessere Antwort. Danke dir. Das Direktivenformat .strftime("%9N")kann ebenfalls verwendet werden. ruby-doc.org/core-2.3.1/Time.html#method-i-strftime
rplaurindo
13

Wenn Sie ein Time- Objekt mit abrufen Time.now, wird beim Aufrufen #to_iein Unix-Zeitstempel (Sekunden ab Epoche) zurückgegeben. #to_fgibt Sekundenbruchteile an, mit denen Sie Millisekunden aus der Epoche abrufen können:

Time.now.to_f * 1000
Levinalex
quelle
3
Dies fälscht die Millisekunden
Brauliobo
0

Die typisierte Ganzzahl (1e6 * Time.now.to_f) gibt ein Bignum zurück, das die Millisekunden aufnehmen kann

Chava
quelle