rails - ¿Cómo convertir una marca de tiempo de Unix(segundos desde la época) a Ruby DateTime?
ruby time (6)
Esto le indica la fecha de la cantidad 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 la hora actual, estoy respondiendo la pregunta que se imprime 047-05-14 05:16:16 +0000
(1 billón de segundos en el futuro)
o si quiere contar mil millones de segundos desde una hora 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 billón de segundos en:" + tiempo)
¿Cómo convertir una marca de tiempo Unix (segundos desde la época) a Ruby DateTime?
Perdón, breve momento de fallo de sinapsis. Aquí está la respuesta real.
require ''date''
Time.at(seconds_since_epoch_integer).to_datetime
Breve ejemplo (esto toma 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 adicional (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 : hice una evaluación comparativa de las principales soluciones en este hilo mientras trabajaba en un servicio de alta disponibilidad hace una o dos semanas, y me sorprendió descubrir 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>
Si solo desea una fecha, puede hacer Date.strptime(invoice.date.to_s, ''%s'')
donde invoice.date
viene en forma de Fixnum
y luego se convierte en una String
.
Un comando para convertir la fecha y la hora al formato Unix y luego a la cadena
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 se usa strftime para formatear la fecha.
Ejemplo:
irb(main):034:0> DateTime.strptime("1410321600",''%s'').strftime("%d %m %y")
"10 09 14"
DateTime.strptime
puede manejar segundos desde la época. El número se debe convertir en una cadena:
require ''date''
DateTime.strptime("1318996912",''%s'')
Manejo de zona horaria
Solo quiero aclarar, aunque esto se ha comentado para que las futuras personas 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 genera un objeto de hora UTC, mientras que
Time.at(1318996912) # => 2011-10-19 00:01:52 -0400
muestra un valor de retorno en la zona horaria LOCAL, normalmente requiere un argumento FixNum, pero el objeto Tiempo en sí sigue en UTC aunque la pantalla no lo esté.
Entonces, aunque pasé el mismo número entero a ambos métodos, aparentemente dos resultados diferentes debido a cómo funciona el método #to_s
la clase. 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 sigue siendo verdadera. Nuevamente, esto se debe a que los valores son básicamente los mismos (aunque las clases son diferentes, 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 las cadenas, podemos ver que son de hecho al mismo tiempo, simplemente impresas en diferentes zonas horarias.
Método de aclaración de argumentos
Los documentos también dicen "Si se da un argumento numérico, el resultado está en la 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. Entonces, 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 completamente y totalmente incorrecto en todos los sentidos ****