92

I have a timestamp that is in UTC

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

I need to convert it into ISO 8601

"2010-10-29 06:09Z"

The documentation is confusing as hell - what is the easiest way to do that?

4 Answers 4

211

I think you're trying to trick us.

The input date to your question is the 25th of October, 2010, whilst the output is the 29th of October, 2010. Well played!

Continuing on this nit-picking thread: your times are also completely different and you're missing the seconds from the output time.

Now for the true answer.

A little factoid first though: the ISO 8601 output in Ruby is similar to the "Combined date and time" output from ISO 8601's Wikipedia page.

You've got a string and so you'll need to convert it into a Time object which you can do with to_time. Then it's simply a matter of calling iso8601 on that object to get the ISO 8601 version:

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

The to_time method is courtesy of Rails, whilst the iso8601 is courtesy of Ruby's standard library.

5
  • 7
    Good answer, but I didn't get the first part (was that supposed to be humor?) Commented Oct 30, 2010 at 17:01
  • 5
    Damn! you saw through my plot to trick you folks. =P Thanks for the great answer, i wonder why they do not just write that in the documentation!
    – meow
    Commented Oct 30, 2010 at 18:30
  • 15
    @Mark Thomas: yes it was supposed to be humour. He gave an input and an output time that wouldn't match, ever. Tricksie little hobbit!
    – Ryan Bigg
    Commented Oct 30, 2010 at 20:01
  • This works, but although his question asked how to do it in ruby, it didn't assume it was in the rails environment.
    – courtsimas
    Commented Feb 2, 2015 at 21:16
  • 1
    Related, thanks for pointing me at 'to_time' ~ Time.now.iso8601 formats like "2010-10-25T23:48:46Z", if you want to use '+00:00' instead of 'Z' (which I had to for a legacy system) Time.now.to_time.iso8601 appears to do this.
    – lucygenik
    Commented Aug 19, 2015 at 21:40
23

After much experimenting, I find the Time library's parser to be better than DateTime, although the reasons escape me at the moment. With that caveat, I always use Time rather than DateTime for this kind of stuff, and the ruby documentation is also difficult to grok as to why this is so,

require 'time'
puts Time.parse("2010-10-25 23:48:46 UTC").iso8601
"2010-10-25T23:48:46Z"
1
  • 6
    good pure ruby solution. Just want to add, if original time is not UTC, you may want this: Time.parse("...").utc.iso8601, otherwize you'll get the time suffixed with +03:00 or some other value depending on the timezone original time string is given with. I mean instead of Z. Commented Jun 22, 2016 at 10:20
6

Note: you have to convert (parse) a time string into a time object before you can apply the to_time method.

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

Correct procedure:

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

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

Adding an answer to this super old question because if you're using Rails, there is no need to convert/parse it in the way the other answers here are telling you to do:

  • If it's already a timestamp (e.g., a created_at or updated_at attribute), you can directly call the iso8601 method on that timestamp (e.g., object.created_at.iso8601).
  • The iso8601 method also accepts a numeric argument to display fractional digits; you would use this if you want 2020-04-06T19:16:55.604Z instead of 2020-04-06T19:16:55Z.

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.