Conversión de la marca de tiempo UTC a ISO 8601 en Ruby

85

Tengo una marca de tiempo en UTC

"2010-10-25 23:48:46 UTC"

Necesito convertirlo a ISO 8601

"2010-10-29 06: 09Z"

La documentación es muy confusa, ¿cuál es la forma más sencilla de hacerlo?

ming yeow
fuente

Respuestas:

185

Creo que estás intentando engañarnos.

La fecha de entrada de su pregunta es el 25 de octubre de 2010 , mientras que la salida es el 29 de octubre de 2010 . ¡Bien jugado!

Continuando con este hilo puntiagudo: sus tiempos también son completamente diferentes y se están perdiendo los segundos del tiempo de salida.

Ahora la verdadera respuesta.

Sin embargo, primero un pequeño dato: la salida ISO 8601 en Ruby es similar a la salida "Fecha y hora combinadas" de la página de Wikipedia de ISO 8601 .

Tienes una cadena y, por lo tanto, deberás convertirla en un Timeobjeto con el que puedas hacer to_time. Entonces es simplemente una cuestión de llamar iso8601a ese objeto para obtener la versión ISO 8601:

"2010-10-25 23:48:46 UTC".to_time.iso8601

El to_timemétodo es cortesía de Rails, mientras que el iso8601es cortesía de la biblioteca estándar de Ruby.

Ryan Bigg
fuente
7
Buena respuesta, pero no obtuve la primera parte (¿se suponía que era humor?)
Mark Thomas
5
¡Maldición! Viste a través de mi plan para engañarlos. = P Gracias por la gran respuesta, me pregunto por qué no escriben eso en la documentación.
ming yeow
13
@Mark Thomas: sí, se suponía que era humor. Dio una entrada y una salida que nunca coincidirían. ¡Tricksie pequeño hobbit!
Ryan Bigg
Esto funciona, pero aunque su pregunta era cómo hacerlo en ruby, no asumía que estaba en el entorno de los rieles.
courtimas
1
Relacionado, gracias por señalarme 'to_time' ~ Time.now.iso8601 formatos como "2010-10-25T23: 48: 46Z", si quieres usar '+00: 00' en lugar de 'Z' (que tenía para un sistema heredado) Parece que Time.now.to_time.iso8601 hace esto.
lucygenik
21

Después de mucho experimentar, encuentro que el analizador de la biblioteca Time es mejor que DateTime, aunque las razones se me escapan en este momento. Con esa salvedad, siempre uso Time en lugar de DateTime para este tipo de cosas, y la documentación de Ruby también es difícil de asimilar en cuanto a por qué esto es así,

require 'time'
puts Time.parse("2010-10-25 23:48:46 UTC").iso8601
"2010-10-25T23:48:46Z"
Steeve McCauley
fuente
5
buena solución de rubí puro. Solo quiero agregar, si la hora original no es UTC, es posible que desee esto Time.parse("...").utc.iso8601:, de lo contrario, obtendrá la hora con el sufijo +03:00o algún otro valor dependiendo de la zona horaria con la que se da la cadena de hora original. Quiero decir en lugar de Z.
Akostadinov
4

Nota: debe convertir (analizar) una cadena de tiempo en un objeto de tiempo antes de poder aplicar el método to_time.

ruby-1.9.2-p180 :016 > "2010-10-25 23:48:46 UTC".to_time.iso8601
NoMethodError: undefined method `to_time' for "2010-10-25 23:48:46 UTC":String
    from (irb):16

Procedimiento correcto:

irb> ut = DateTime.parse("2010-10-25 23:48:46 UTC")

irb> ut.iso8601
 => "2010-10-25T23:48:46+00:00" 
Aerodame
fuente
1

Agregando una respuesta a esta pregunta súper antigua porque si está usando Rails, no es necesario convertirlo / analizarlo de la forma en que las otras respuestas aquí le dicen que haga:

  • Si ya es una marca de tiempo (por ejemplo, un atributo created_ato updated_at), puede llamar directamente al iso8601método en esa marca de tiempo (por ejemplo, object.created_at.iso8601).
  • El iso8601método también acepta un argumento numérico para mostrar dígitos fraccionarios; usaría esto si lo desea en 2020-04-06T19:16:55.604Zlugar de 2020-04-06T19:16:55Z.

https://api.rubyonrails.org/v5.2.4/classes/ActiveSupport/TimeWithZone.html#method-i-iso8601

Allison
fuente