Risposte:
DateTime.strptime
può gestire i secondi dall'epoca. Il numero deve essere convertito in una stringa:
require 'date'
DateTime.strptime("1318996912",'%s')
%Q
tho.
Time
sia necessario invece di DateTime
. Quindi usa Time.strptime("1318996912345",'%Q').to_f
e vedrai i millisecondi preservati, mentre DateTime.strptime("1318996912345",'%Q').to_f
non li conserva.
Siamo spiacenti, breve momento del fallimento della sinapsi. Ecco la vera risposta.
require 'date'
Time.at(seconds_since_epoch_integer).to_datetime
Breve esempio (questo tiene conto dell'attuale fuso orario del sistema):
$ date +%s
1318996912
$ irb
ruby-1.9.2-p180 :001 > require 'date'
=> true
ruby-1.9.2-p180 :002 > Time.at(1318996912).to_datetime
=> #<DateTime: 2011-10-18T23:01:52-05:00 (13261609807/5400,-5/24,2299161)>
Ulteriore aggiornamento (per UTC):
ruby-1.9.2-p180 :003 > Time.at(1318996912).utc.to_datetime
=> #<DateTime: 2011-10-19T04:01:52+00:00 (13261609807/5400,0/1,2299161)>
Aggiornamento recente : ho confrontato le migliori soluzioni in questo thread mentre lavoravo su un servizio HA una o due settimane fa e sono stato sorpreso di scoprire che Time.at(..)
supera le prestazioni DateTime.strptime(..)
(aggiornamento: aggiunto più benchmark).
# ~ % ruby -v
# => ruby 2.1.5p273 (2014-11-13 revision 48405) [x86_64-darwin13.0]
irb(main):038:0> Benchmark.measure do
irb(main):039:1* ["1318996912", "1318496912"].each do |s|
irb(main):040:2* DateTime.strptime(s, '%s')
irb(main):041:2> end
irb(main):042:1> end
=> #<Benchmark ... @real=2.9e-05 ... @total=0.0>
irb(main):044:0> Benchmark.measure do
irb(main):045:1> [1318996912, 1318496912].each do |i|
irb(main):046:2> DateTime.strptime(i.to_s, '%s')
irb(main):047:2> end
irb(main):048:1> end
=> #<Benchmark ... @real=2.0e-05 ... @total=0.0>
irb(main):050:0* Benchmark.measure do
irb(main):051:1* ["1318996912", "1318496912"].each do |s|
irb(main):052:2* Time.at(s.to_i).to_datetime
irb(main):053:2> end
irb(main):054:1> end
=> #<Benchmark ... @real=1.5e-05 ... @total=0.0>
irb(main):056:0* Benchmark.measure do
irb(main):057:1* [1318996912, 1318496912].each do |i|
irb(main):058:2* Time.at(i).to_datetime
irb(main):059:2> end
irb(main):060:1> end
=> #<Benchmark ... @real=2.0e-05 ... @total=0.0>
Time.at
superi DateTime.strptime
. Quest'ultimo deve analizzare una stringa, che è generalmente molto più lenta rispetto al prendere direttamente un numero.
DateTime.strptime
perché sta creando due nuove stringhe ogni iterazione che è molto costoso. Non è solo la stringa che analizza come ha detto
Gestione del fuso orario
Voglio solo chiarire, anche se questo è stato commentato in modo che le persone future non perdano questa distinzione molto importante.
DateTime.strptime("1318996912",'%s') # => Wed, 19 Oct 2011 04:01:52 +0000
visualizza un valore di ritorno in UTC e richiede che i secondi siano una stringa e genera un oggetto Time UTC, mentre
Time.at(1318996912) # => 2011-10-19 00:01:52 -0400
visualizza un valore di ritorno nel fuso orario LOCAL, normalmente richiede un argomento FixNum, ma l'oggetto Time stesso è ancora in UTC anche se il display non lo è.
Quindi, anche se ho passato lo stesso numero intero a entrambi i metodi, apparentemente ho ottenuto due risultati diversi a causa di come funziona il #to_s
metodo della classe . Tuttavia, poiché @Eero ha dovuto ricordarmi due volte di:
Time.at(1318996912) == DateTime.strptime("1318996912",'%s') # => true
Un confronto di uguaglianza tra i due valori restituiti restituisce comunque true. Ancora una volta, questo perché i valori sono sostanzialmente gli stessi (anche se classi diverse, il #==
metodo si occupa di questo per te), ma il #to_s
metodo stampa stringhe drasticamente diverse. Sebbene, se osserviamo le stringhe, possiamo vedere che sono effettivamente allo stesso tempo, appena stampate in diversi fusi orari.
Chiarimento dell'argomento del metodo
I documenti dicono anche "Se viene fornito un argomento numerico, il risultato è in ora locale". il che ha senso, ma è stato un po 'confuso per me perché non forniscono alcun esempio di argomenti non interi nei documenti. Quindi, per alcuni esempi di argomenti non interi:
Time.at("1318996912")
TypeError: can't convert String into an exact number
non puoi usare un argomento String, ma puoi usare un argomento Time in Time.at
e restituirà il risultato nel fuso orario dell'argomento:
Time.at(Time.new(2007,11,1,15,25,0, "+09:00"))
=> 2007-11-01 15:25:00 +0900
Punti di riferimenti
Dopo una discussione con @AdamEberlin sulla sua risposta, ho deciso di pubblicare benchmark leggermente modificati per rendere tutto il più uguale possibile. Inoltre, non voglio mai doverli ricostruire di nuovo, quindi questo è un posto buono come un altro per salvarli.
Time.at (int) .to_datetime ~ 2.8x più veloce
09:10:58-watsw018:~$ ruby -v
ruby 2.3.7p456 (2018-03-28 revision 63024) [universal.x86_64-darwin18]
09:11:00-watsw018:~$ irb
irb(main):001:0> require 'benchmark'
=> true
irb(main):002:0> require 'date'
=> true
irb(main):003:0>
irb(main):004:0* format = '%s'
=> "%s"
irb(main):005:0> times = ['1318996912', '1318496913']
=> ["1318996912", "1318496913"]
irb(main):006:0> int_times = times.map(&:to_i)
=> [1318996912, 1318496913]
irb(main):007:0>
irb(main):008:0* datetime_from_strptime = DateTime.strptime(times.first, format)
=> #<DateTime: 2011-10-19T04:01:52+00:00 ((2455854j,14512s,0n),+0s,2299161j)>
irb(main):009:0> datetime_from_time = Time.at(int_times.first).to_datetime
=> #<DateTime: 2011-10-19T00:01:52-04:00 ((2455854j,14512s,0n),-14400s,2299161j)>
irb(main):010:0>
irb(main):011:0* datetime_from_strptime === datetime_from_time
=> true
irb(main):012:0>
irb(main):013:0* Benchmark.measure do
irb(main):014:1* 100_000.times {
irb(main):015:2* times.each do |i|
irb(main):016:3* DateTime.strptime(i, format)
irb(main):017:3> end
irb(main):018:2> }
irb(main):019:1> end
=> #<Benchmark::Tms:0x00007fbdc18f0d28 @label="", @real=0.8680500000045868, @cstime=0.0, @cutime=0.0, @stime=0.009999999999999998, @utime=0.86, @total=0.87>
irb(main):020:0>
irb(main):021:0* Benchmark.measure do
irb(main):022:1* 100_000.times {
irb(main):023:2* int_times.each do |i|
irb(main):024:3* Time.at(i).to_datetime
irb(main):025:3> end
irb(main):026:2> }
irb(main):027:1> end
=> #<Benchmark::Tms:0x00007fbdc3108be0 @label="", @real=0.33059399999910966, @cstime=0.0, @cutime=0.0, @stime=0.0, @utime=0.32000000000000006, @total=0.32000000000000006>
**** modificato per non essere completamente e totalmente errato in ogni modo ****
**** benchmark aggiunti ****
Time.at(1318996912) == DateTime.strptime("1318996912",'%s')
in un fuso orario non UTC e vedrai!
Time.use_zone "Samoa" do Time.at(1318996912) == DateTime.strptime("1318996912",'%s') end
per verificare che i tempi siano uguali, non esiste un timestamp LOCALE e in entrambi i casi il timestamp Unix viene interpretato come in UTC. Time.at
presenta l'oggetto Time risultante nel fuso orario locale e DateTime.strptime
presenta l'oggetto DateTime risultante in UTC, ma indipendentemente dalla presentazione sono uguali, poiché sono il momento equivalente nel tempo.
Time.at(1318996912) # => 2011-10-19 00:01:52 -0400
visualizza un valore di ritorno nel fuso orario LOCALE non sembra essere preciso ... Puoi verificarlo? Credo che la tua affermazione sarebbe vera solo se avessi usatoTime.zone.at(1318996912)
Un comando per convertire l'ora della data in formato Unix e quindi in stringa
DateTime.strptime(Time.now.utc.to_i.to_s,'%s').strftime("%d %m %y")
Time.now.utc.to_i #Converts time from Unix format
DateTime.strptime(Time.now.utc.to_i.to_s,'%s') #Converts date and time from unix format to DateTime
infine strftime viene utilizzato per formattare la data
Esempio:
irb(main):034:0> DateTime.strptime("1410321600",'%s').strftime("%d %m %y")
"10 09 14"
Time.now.utc.to_i
.
Questo ti dice la data del numero di secondi in futuro dal momento in cui esegui il codice.
time = Time.new + 1000000000 #date in 1 billion seconds
puts (tempo)
in base all'ora corrente sto rispondendo alla domanda che stampa 047-05-14 05:16:16 +0000
(1 miliardo di secondi in futuro)
o se vuoi contare miliardi di secondi da un determinato momento, è in formato Time.mktime(year, month,date,hours,minutes)
time = Time.mktime(1987,8,18,6,45) + 1000000000
mette ("Avrei 1 miliardo di secondi dopo:" + tempo)