2011-10-19 2 views

risposta

275

DateTime.strptime in grado di gestire secondi da epoca. Il numero deve essere convertito in una stringa:

require 'date' 
DateTime.strptime("1318996912",'%s') 
+4

Questo non gestisce i secondi frazionari –

+28

Gestisce i millisecondi con''% Q' tho. –

+0

grazie @TheMiniJohn – KingChintz

541

Siamo spiacenti, breve momento di fallimento della sinapsi. Ecco la vera risposta.

require 'date' 

Time.at(seconds_since_epoch_integer).to_datetime 

Breve esempio (questo prende in considerazione il fuso orario attuale 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)> 

recente aggiornamento: Ho confrontato le migliori soluzioni in questo thread mentre lavoravo su un HA assistenza una o due settimane fa, ed è stato sorpreso di scoprire che Time.at(..) ha prestazioni superiori a 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> 
+1

Grazie ... La seguente risposta è un po 'più concisa, ho trovato Time.at ma cercavo di trovare un equivalente DateTime. – Tronathan

+26

È divertente ma Time.at(). To_datetime sembra più piacevole di DateTime.strptime() semplicemente a causa della leggibilità ... Almeno per me comunque – tybro0103

+29

Questo non è lo stesso del precedente, Time.at assume il fuso orario corrente, dove DateTime.strptime utilizza UTC. –

0

Se si voleva solo una data, si può fare Date.strptime(invoice.date.to_s, '%s') dove invoice.date si presenta sotto forma di un Fixnum e poi convertito in un String.

+0

'Time.at (1500923406) .to_date.to_s' =>' "2017-07-24" ' – Chloe

36

Time Zone Handling

Voglio solo chiarire, anche se questo è stato commentato così la gente futuri non perdere questa importante distinzione.

DateTime.strptime("1318996912",'%s') # => Wed, 19 Oct 2011 04:01:52 +0000 

visualizza un valore di ritorno nel UTC e richiede i secondi come una stringa ed emette un oggetto UTC Tempo, considerando

Time.at(1318996912) # => 2011-10-19 00:01:52 -0400 

visualizza un valore di ritorno nel fuso orario locale, richiede normalmente un Fixnum argomento, 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, ho apparentemente due risultati diversi a causa di come funziona il metodo #to_s della classe. Tuttavia, come @Eero ha dovuto ricordare a me due volte di:

Time.at(1318996912) == DateTime.strptime("1318996912",'%s') # => true 

Un confronto di uguaglianza tra i due valori di ritorno restituisce ancora vero. Di nuovo, questo è perché i valori sono fondamentalmente gli stessi (anche se di classi diverse, il metodo #== si prende cura di questo per voi), ma il metodo #to_s stampa stringhe drasticamente differenti. Sebbene, se osserviamo le stringhe, possiamo vedere che sono effettivamente la stessa volta, stampate solo in fusi orari diversi.

Metodo argomento Chiarificazione

La documentazione anche dire "Se viene dato un argomento numerico, il risultato è in tempo locale". il che ha senso, ma mi confondeva un po 'perché non fornivano esempi di argomenti non interi nei documenti.Così, per alcuni non interi esempi argomento:

Time.at("1318996912") 
TypeError: can't convert String into an exact number 

non è possibile utilizzare un argomento stringa, ma è possibile utilizzare un argomento di tempo 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 

**** a cura di non essere completamente e totalmente non corretta in tutti i modi ****

+3

Sembra plausibile e ho già eseguito il upvoted (non è possibile annullare l'operazione adesso), ma dopo aver verificato che il tuo reclamo relativo a UTC non è vero. L'oggetto DateTime/Time risultante sarà in UTC rispetto a local, sì, ma il timestamp originale viene interpretato come in UTC in entrambi i casi! Quindi il momento nel tempo è uguale indipendentemente dal metodo. Prova 'Time.at (1318996912) == DateTime.strptime (" 1318996912 ", '% s')' in un fuso orario non UTC e vedrai! – Eero

+0

Grazie, @Eero. Correggerò questo errore – WattsInABox

+4

Mi dispiace, ma quello che hai corretto è ancora sbagliato!:-) Esegui 'Time.use_zone" Samoa "do Time.at (1318996912) == DateTime.strptime (" 1318996912 ", '% s') end' per verificare che i tempi siano uguali, non esiste un timestamp LOCAL e in entrambi i casi il timestamp Unix viene interpretato come in UTC. 'Time.at' * presenta * l'oggetto Ora 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 in tempo. – Eero

6

Un comando per convertire data e ora in formato Unix e poi a 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 

finalmente strftime viene utilizzato per il formato della data

Esempio:

irb(main):034:0> DateTime.strptime("1410321600",'%s').strftime("%d %m %y") 
    "10 09 14" 
1

Questo indica la data del numero di secondi, in futuro, dal momento in cui si esegue il codice.

time = Time.new + 1000000000 #date in 1 billion seconds 

puts (tempo)

secondo l'ora corrente sto rispondendo alla domanda la stampa 047-05-14 05:16:16 +0000 (1 miliardo di secondi in futuro)

o se si desidera contare miliardo di secondi da un particolare tempo, è in formato Time.mktime(year, month,date,hours,minutes)

time = Time.mktime(1987,8,18,6,45) + 1000000000 

puts ("sarei 1 miliardo di secondi di vita su:" + tempo)