Come ottenere l'ora corrente come numero intero di 13 cifre in Ruby?


88

Ho questa jQueryfunzione che restituisce l'ora corrente come numero di millisecondi dall'epoca (1 gennaio 1970):

time = new Date().getTime();

C'è un modo per fare lo stesso in Ruby?

In questo momento, sto usando Ruby Time.now.to_iche funziona alla grande ma restituisce un numero intero di 10 cifre (numero di secondi)

Come posso ottenere che visualizzi il numero di millisecondi, come in jQuery?


5
Questa non è una "funzione jQuery", è semplicemente ECMAScript (javascript). Forse è questo che ha spinto il -1, un po 'duro però.
RobG

Risposte:


151
require 'date'

p DateTime.now.strftime('%s') # "1384526946" (seconds)
p DateTime.now.strftime('%Q') # "1384526946523" (milliseconds)

31
Nota per gli utenti Rails: il strftimemetodo fornito da ActiveSupport::TimeWithZonenon include gli specificatori %se %Q. Dovrai prima convertire in un semplice Ruby DateTime, usando il to_datetimemetodo.
Lonnon Foster

6
@LonnonFoster Ora funziona (appena testato nella console Rails).
Nikola Stojaković

Ciao, come posso fare la stessa cosa, ma non per ora, ma piuttosto da un campo data?
Tomer


101

Javascript gettime()restituisce il numero di millisecondi dall'epoca.

Ruby Time.now.to_iti darà il numero di secondi trascorsi dall'epoca. Se lo cambi in Time.now.to_f, ottieni ancora secondi ma con una componente frazionaria. Basta moltiplicarlo per 1.000 e avrai millisecondi. Quindi utilizzare #to_iper convertirlo in un numero intero. E ti ritroverai con:

(Time.now.to_f * 1000).to_i

Grazie mille per la spiegazione! Ancora nuovo a tutta questa faccenda ... Non so quale risposta contrassegnare come corretta in realtà ...
Tintin81

1
Solo per ulteriori informazioni, Time.nowviene da Ruby poiché Time.currentproviene da Rails. Così Time.currentviene riconosciuto dal fuso orario dell'applicazione Rails e Time.nowutilizza il fuso orario del server. Nella mia esperienza, usa sempre Time.currentsulla tua applicazione Rails per la coerenza del fuso orario
vutran

1
No, non dovresti assolutamente usarlo Time.currentqui, ci vuole più tempo per costruire e poiché lo stai convertendo immediatamente in un timestamp unix, non ti interessa affatto la coerenza del fuso orario. (I timestamp Unix si riferiscono sempre a UTC). Quindi, mentre quello che stai dicendo è vero nel 99% dei casi, questo in termini di prestazioni cade nell'ultimo 1%.
The Pellmeister

1
Questo è il mio approccio preferito. Una cosa che mi piace fare è aumentare la classe Time per aggiungere un :epochmetodo: class Time def epoch (self.to_f * 1000) .to_i end end
Matt Welke

1
questo falsifica i millisecondi
brauliobo

31

(Time.now.to_f * 1000).to_i dovrebbe fare la stessa cosa.


1
@brauliobo cosa sono i falsi millisecondi?
Erik Rothoff

1
@brauliobo Non lo fa, poiché to_finclude i millisecondi come decimale.
CashIsClay

20

Usando strftime, puoi ottenere il numero di secondi e aggiungere frazioni di millisecondi (o unità più piccole, se necessario):

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

Nota però che questo non arrotonda, tronca, come puoi vedere con to_fo se esci a microsecondi:

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

e la soluzione to_f/ to_iha lo stesso problema:

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

quindi se ti interessa davvero la precisione del millisecondo, una scommessa migliore potrebbe essere to_fcon round:

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

Detto questo, come indicato nella documentazione , "IEEE 754 doppio non è sufficientemente accurata per rappresentare il numero di nanosecondi dal Epoch", quindi se veramente veramente cura, considera to_rinvece che to_f-

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

- anche se se stai arrotondando solo a millisecondi probabilmente stai bene.


18

Stai attento, non ti confondere. Il fatto che Ruby supporti l'idea di frazioni di secondo come float non lo rende effettivamente un numero in virgola mobile. Mi sono messo nei guai con questo quando stavo facendo i confronti del tempo di timestamp di Wireshark in Python ... i calcoli del tempo in pcap-ng semplicemente non funzionavano. È stato solo quando ho trattato le due parti (secondi interi e nanosecondi interi) poiché entrambi gli interi sono stato in grado di ottenere numeri corretti.

Questo perché i numeri in virgola mobile hanno problemi di precisione . In effetti, un po 'di Ruby ti mostrerà che to_f non è uguale, diciamo, nsec:

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

Programmatore avvertimento. Potresti essere sicuro di 3 cifre significative, ma resta il fatto: i numeri in virgola mobile sui computer sono approssimazioni. I contatori di nanosecondi sui computer moderni sono numeri interi.


La risposta migliore. Grazie. .strftime("%9N")Può essere utilizzato anche il formato direttiva . ruby-doc.org/core-2.3.1/Time.html#method-i-strftime
rplaurindo

13

Ottieni un oggetto Time con Time.now, la chiamata #to_irestituisce un timestamp Unix (secondi da epoch). #to_ffornisce frazioni di secondo che puoi usare per ottenere millisecondi dall'epoca:

Time.now.to_f * 1000

3
questo falsifica i millisecondi
brauliobo

0

Il typecast Integer (1e6 * Time.now.to_f) restituisce un Bignum che può contenere i millisecondi

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.