We’ve all had those tough conversations on how best to exchange dates between two systems: “is DD-MM-YYYY good for everyone?” “what about YYYY/MM/DD” “we could just use Epoch timestamps”…
Each option is rife with problems; some don’t convey enough info, some are too ambiguous, and others are hard on the human eye. Compounding these difficulties are the myriad of standards that work across different systems.
Luckily there is a solution, It is flexible, readable and unambiguous. ISO8601.
ISO8601 is simply the best standards to use. It can provide the maximum amount of info reasonably required when interchanging dates between systems. It can provide units all the way down to second decimals. It includes support for time zones and strictly specifies the order of each date fragment, all while still being reasonably terse. It looks something like this:
Let’s dissect ISO8601 at a deeper level and further prove why you should be using it.
ISO8601 defines the exact order at which the date should be represented, in a system that is called “big endian” (smallest last). This means that the biggest unit comes first, followed by the next, all the way down to the smallest. It also says that the biggest unit needed is year, so ISO8601 dates have to be ordered as
YYYY-MM-DD, times have to be ordered to
HH:MM:SS, followed by an optional second decimal. This is great because not only is this completely unambiguous (you’ll never confuse MM for DD again) but it also makes it very easy to read (everything is in its expected place). It just makes sense.
Time zone support
It supports time zones, and it has a predefined way of doing so, like
+HHMM). Date formats like Seconds-from-Epoch just cannot convey this and so - as well as being completely unreadable - they are not as well suited as ISO8601.
Send as much or as little as you need
Inherently ISO says you can optionally send as much data as you want to, and it still be a valid ISO string, so for example
YYYY would be a valid ISO date, as would
YYYY-MM-DDTHH. You can supply the time zone, or omit it, up to you. You can only omit going down though, so a date like
MM-DD isn’t valid, because it is missing the year.
The upshot of this flexibility though, and one that is pretty much universally missed by languages is that you can also do crazy stuff like provide seconds to as many decimal places as you want. So a date like
2009-09-09T09:09:09.00000000000000000009 is totally valid. ISO8601's biggest gain is also its biggest pain, which makes it very difficult to code a reliable parser for the standard. Some small but annoying quirks to look out for are:
Unlimited decimals allowed for seconds, The
T separator between the date and time can be pretty much anything time zone can be omitted, or Z, it can have a
: to separate hours from minutes, or not.
Z for the time zone. See how this can get pretty complex pretty quickly?
An awesome but oft overlooked part of ISO8601 is intervals. For example you are making a calendar, and you have a meeting that lasts 2 hours on it, with ISO8601 intervals you can express this as a string format, rather than using something ghastly like seconds or milliseconds:
The nice thing about ISO intervals is that they are human readable, they are easy enough to parse, and they follow stricter standards. An ISO interval must start with a
P, standing for Period. From there it is simply a number, followed by a unit-like designator, for example months are M and days are D. To separate time from dates, use a
T - just like ISO date times.
Start using ISO8601 today
If you're sending dates across systems, there really is no excuse not to be using ISO8601. Tempus will make it super easy. Try it and never revert to the bad old ways.
If you're already using ISO8601, spread the word! If have any tips for readers, or want to shout at me for because you are still hanging on to Epoch timestamps, then you can do so by tweeting me, @keithamus, on Twitter.