ISO8601 is a standard for representing date/time information as a string. ISO8601 dates look like this: 2009-10-26T04:47:09Z.

There are a lot of good reasons to store dates in the ISO8601 format. The format is…

  • Unambiguous. There is never any question how to interpret them.
  • Human-readable. You can look at dates stored in ISO8601 and interpret them easily.
  • Widely-supported. All major programming languages have libraries for parsing and writing ISO8601 dates.
  • Sortable. If you follow a few simple rules, ISO8601 dates sort lexicographically into the order you would expect.

That last property makes ISO8601 a particularly good candidate for date/time storage in simple non-relational data stores like Amazon’s SimpleDB. Storing dates as ISO8601 lets you sort records by date in data stores which don’t support a native date/time data type – without sacrificing human-readability.

Using ISO8601 from Ruby couldn’t be simpler, if you know where to look for the tools. If you look at the Ruby Time class by itself, you won’t find any reference to ISO8601. The secret is to require the ‘time’ library:

irb(main):001:0> time = Time.now.utc.iso8601
NoMethodError: undefined method `iso8601' for Mon Oct 26 04:46:57 UTC 2009:Time
        from (irb):1
        from :0
irb(main):002:0> require 'time'
=> true
irb(main):003:0> time = Time.now.utc.iso8601
=> "2009-10-26T04:47:09Z"
irb(main):004:0> Time.iso8601(time)
=> Mon Oct 26 04:47:09 UTC 2009

Note the use of utc to convert the local time into universal time (aka Greenwich Mean). This is important if you want your time strings to be lexicographically sortable. The “Z” on the end of the ISO8601 date indicates that it is in UTC, not a local time zone.

Published by Avdi Grimm

9 Comments

  1. require 'rss' works because it is requiring 'time'.
    If you just want the iso8601 support, you can go with: require 'time'

    Also, Time#iso8601 takes a handy optional argument for the number of fractional digits at the end.
    I've had to use this to interact with brittle external services, for example.

    Reply
  2. require 'rss' works because it is requiring 'time'.
    If you just want the iso8601 support, you can go with: require 'time'

    Also, Time#iso8601 takes a handy optional argument for the number of fractional digits at the end.
    I've had to use this to interact with brittle external services, for example.

    Reply
  3. Thanks, I've updated the post!

    Reply
  4. What is about time periods ? How can I get format like this PT1H30M ?

    Reply
  5. Great post regarding iso8601. I was trying to load a Time object from a YAML config file and everything else I did just returned a string representation of the date. By using the iso8601 format, YAML correctly parses it back to a Time object. 🙂

    Reply
  6. Also, the instance method Date#strftime() returns the ISO-8601 representation of the object. You can give it a formatting string as a parameter to yield the date it represents in other formats.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *