Cómo convertir una marca de tiempo unix (segundos desde época) a Ruby DateTime?
¿Cómo convertir una marca de tiempo Unix (segundos desde época) a Ruby DateTime?
6 answers
DateTime.strptime
puede manejar segundos desde epoch. El número debe convertirse en una cadena:
require 'date'
DateTime.strptime("1318996912",'%s')
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-04 12:31:10
Lo siento, breve momento de falla de la sinapsis. Aquí está la verdadera respuesta.
require 'date'
Time.at(seconds_since_epoch_integer).to_datetime
Breve ejemplo (esto tiene en cuenta la zona horaria actual 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)>
Actualización posterior (para 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)>
Actualización reciente : Comparé las mejores soluciones en este hilo mientras trabajaba en un servicio de HA hace una semana o dos, y me sorprendió encontrar que Time.at(..)
supera a DateTime.strptime(..)
(actualización: se agregaron más puntos de referencia).
# ~ % 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>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-06 02:12:34
Manejo de Zonas Horarias
Solo quiero aclarar, a pesar de que esto ha sido comentado para que las personas futuras no se pierdan esta distinción tan importante.
DateTime.strptime("1318996912",'%s') # => Wed, 19 Oct 2011 04:01:52 +0000
Muestra un valor de retorno en UTC y requiere que los segundos sean una cadena y muestra un objeto de tiempo UTC, mientras que
Time.at(1318996912) # => 2011-10-19 00:01:52 -0400
Muestra un valor devuelto en la zona horaria LOCAL, normalmente requiere un argumento FixNum, pero el objeto Time en sí sigue estando en UTC aunque la visualización no lo esté.
So a pesar de que pasé el mismo entero a ambos métodos, aparentemente dos resultados diferentes debido a cómo funciona el método class' #to_s
. Sin embargo, como @Eero tuvo que recordarme dos veces:
Time.at(1318996912) == DateTime.strptime("1318996912",'%s') # => true
Una comparación de igualdad entre los dos valores de retorno todavía devuelve true. De nuevo, esto se debe a que los valores son básicamente los mismos (aunque diferentes clases, el método #==
se encarga de esto por usted), pero el método #to_s
imprime cadenas drásticamente diferentes. Aunque, si nos fijamos en la cadenas, podemos ver que son de hecho el mismo tiempo, sólo impreso en diferentes zonas horarias.
Método Argumento Clarificación
Los documentos también dicen "Si se da un argumento numérico, el resultado es en hora local."lo cual tiene sentido, pero fue un poco confuso para mí porque no dan ningún ejemplo de argumentos no enteros en los documentos. Por lo tanto, para algunos ejemplos de argumentos no enteros:
Time.at("1318996912")
TypeError: can't convert String into an exact number
No puede usar un argumento de cadena, pero puede usar un argumento de tiempo en Time.at
y devolverá el resultado en la zona horaria del argumento:
Time.at(Time.new(2007,11,1,15,25,0, "+09:00"))
=> 2007-11-01 15:25:00 +0900
* * * * editado para no ser completa y totalmente incorrecto en todos los sentidos * * * *
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-30 20:02:46
Un comando para convertir date time a formato Unix y luego a string
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 se utiliza para formatear la fecha
Ejemplo:
irb(main):034:0> DateTime.strptime("1410321600",'%s').strftime("%d %m %y")
"10 09 14"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-12 15:53:21
Esto le indica la fecha del número de segundos en el futuro desde el momento en que ejecuta el código.
time = Time.new + 1000000000 #date in 1 billion seconds
Pone (tiempo)
De acuerdo con el tiempo actual estoy respondiendo a la pregunta que imprime 047-05-14 05:16:16 +0000
(1 mil millones de segundos en el futuro)
O si desea contar mil millones de segundos de un momento en particular, está en formato Time.mktime(year, month,date,hours,minutes)
time = Time.mktime(1987,8,18,6,45) + 1000000000
Pone ("Tendría 1 mil millones de segundos de edad en:" +tiempo)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-05 03:42:48
Si solo quieres una Fecha, puedes hacer Date.strptime(invoice.date.to_s, '%s')
donde invoice.date
viene en forma deFixnum
y luego se convierte en String
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-10 18:25:09