在Ruby中将UTC时间戳转换为ISO 8601格式

92

我有一个UTC时间戳

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

我需要将其转换为ISO 8601格式

"2010-10-29 06:09Z"

文件说明非常混乱 - 最简单的方法是什么?

4个回答

210

我觉得你在试图愚弄我们。

你问题中的输入日期是2010年10月25日,而输出日期是10月29日2010年。干得漂亮!

继续挑剔一下:你的时间也完全不同,并且输出时间缺少了秒数。

现在到了真正的答案。

先给你一个小秘密:Ruby中的ISO 8601输出类似于ISO 8601的维基百科页面中的"组合日期和时间"输出。

你有一个字符串,所以你需要将其转换为Time对象,可以使用to_time来完成。然后只需调用该对象上的iso8601方法即可获得ISO 8601版本:

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

to_time 方法来自于 Rails,而 iso8601 来自于 Ruby 的标准库。


7
好的回答,但我不明白第一部分(那是要幽默吗?) - Mark Thomas
5
该死!你看穿了我欺骗大家的计划。=P 感谢你提供的出色答案,我想知道为什么他们不在文档中直接写明! - meow
15
@Mark Thomas:是的,这是个幽默。他给了一个不可能匹配的输入和输出时间。这个小精灵真是太狡猾了! - Ryan Bigg
这个方法可行,但是虽然他的问题是如何在Ruby中实现,但它并没有假设它是在Rails环境中。 - courtsimas
1
谢谢您指出了“to_time”功能~ Time.now.iso8601的格式为“2010-10-25T23:48:46Z”。如果您想使用'+00:00'而不是'Z'(我必须用于遗留系统),似乎可以使用Time.now.to_time.iso8601。 - lucygenik

22

经过多次实验,我发现Time库的解析器比DateTime更好,尽管原因此时我无法理解。有了这个警告,我总是使用Time而不是DateTime来处理这种类型的东西,而且ruby文档也很难理解为什么要这样做。

require 'time'
puts Time.parse("2010-10-25 23:48:46 UTC").iso8601
"2010-10-25T23:48:46Z"

6
好的纯Ruby解决方案。只是想补充一下,如果原始时间不是UTC时间,您可能需要使用Time.parse("...").utc.iso8601,否则您会得到带有+03:00或其他取决于原始时间字符串所附带时区的后缀时间。我的意思是用Z代替。 - akostadinov

6
注意:在应用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

正确的步骤:

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

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

2

因为你正在使用Rails,所以我会在这个超级老的问题中添加一个答案,因为没有必要按照其他答案所说的方式进行转换/解析:

  • 如果它已经是时间戳(例如,created_atupdated_at属性),您可以直接调用该时间戳上的iso8601方法(例如,object.created_at.iso8601)。
  • iso8601方法还接受数字参数以显示小数位数;如果您想要2020-04-06T19:16:55.604Z而不是2020-04-06T19:16:55Z,则可以使用此选项。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接