ISO 8601 date formatter
An NSFormatter subclass to convert an ISO 8601 string to an NSDate and back
ISO 8601 provides a standard unambiguous format (several, actually) for dates and times. Unfortunately, NSDateFormatter alone does not completely support ISO 8601; in particular, it does not support week dates or ordinal dates.
This came to my attention when I began writing a patch for Vienna to add support for the
ttl element of RSS 2.0 and the
updateBase elements of RDF Site Summary 1.0's Syndication module (which it borrowed from Open Content Syndication). The latter prescribes a YYYY-MM-DDTHH:MM format for dates. Somehow, I got it into my head that it prescribed ISO 8601 format for dates (as opposed to only the YYYY-MM-DDTHH:MM format), which would have meant that NSDateFormatter wouldn't work.
So, that's why I wrote this parser. I won't need it for Vienna, since RSS 1.0 doesn't actually prescribe ISO 8601 format by name (simply one version of it, which should be perfectly doable with plain Cocoa date-formatting techniques). Adium, however, does use ISO 8601 format in its log format, and so this parser/unparser is being used in Adium X 1.0 and later.
0.7 — 2013-10-09
- Cocoa Touch is now officially supported. 4bc0a08 5d95233
- Added an Xcode project with static library targets. c847ddb 4bc0a08
stringFromObjectValue: now logs to the Console when you hand it a value that isn't an NSDate. Check your Console output after upgrading—you might have had a bug all this time without knowing! 4e05978
- Added proper documentation in the header, compatible with appledoc. f17713f
- Fixed nonsense date components/dates being returned when the input is not a valid date string. 288f757 93bb9df 0cb6442
- Fixed a bug in unparsing where the time zone was wrong (#3). 0e355ee 8f8a2c3 (Thanks, Carl Lindberg)
- Fixed a DST bug in unparsing where the time zone offset was computed in general rather than for the date being unparsed (#6). 5665132 (Thanks, Zachary West) 9e835c8 0d36057
- Fixed AM/PM (or local equivalent) appearing in some locales on iOS devices (#15). 4bc0a08 3f697b5 249b3df (Thanks, Matthias Bauch)
- Fixed another NSDateFormatter-rewriting-formats-to-12-hour-in-some-locales bug. 7c9907f (Thanks, Carl Lindberg)
- (iOS) The class now purges its time zone cache automatically in response to a memory warning. You don't need to do that yourself, anymore, so the method to purge the caches is no longer public. 138e186 3224b32 a9b6973 3f3c3b8
- Added support for strings that specify a fraction of a second. 1d3194b 0b0b1ea (Thanks, Luke Redpath)
- Added support for non-ASCII time separator characters. 47d5035
- Added support for a time zone separator. 8198f1b 3bd0c07 17c15ed (Thanks to Daniel Tull for the suggestion.)
- Fixed the parser's response to being passed
nil. 3c12abc 4980ee6
- Fixed (I think) #5: dates being formatted with DST applied when they shouldn't. 7368fe8
stringFromObjectValue: to behave as NSFormatter's documentation says it should. 3846f80 9754438
- Added real unit tests based on OCUnit. c847ddb aa1c2cb daf3cc9 9029991 d92aeb6 b412326 (Thanks, Luke Redpath) 45af6bd cfedd75 af0b93c 6a7fd88 9e835c8 9e835c8 0d36057 7368fe8 4bc0a08 3f697b5 8f8a2c3 51c1130 e888681 13a872d f49193c 10ed166 d5fdf51 4980ee6 3846f80 288f757 93bb9df daa45fb 2d61bd0 9f35c4a 8f95099 d62777a 138e186 2a63718
- Fixed range computation for strings where the date portion ends with a 'Z'. 8f95099 efa095e 808e8c4
- Fixed some formats with missing hyphens being wrongly accepted when strict mode is on. 9f35c4a c4e0f15
- Fixed week date strings not having a 'T' between date and time. 7b6fd9f 6a1b66b
- Fixed week date strings having wrong time zones. 9f6af7c
- Strings that specify intervals (as specified by ISO 8601) are now explicitly rejected, at least for now (#20). 6d539db 51c1130 bf6a2db 6aef760 (Thanks, Blake Watters)
ISO8601DefaultTimeSeparatorCharacter is now declared as
const. I hope none of you were relying on changing that. db9877c
- Upgraded this README to Markdown. 103f666 fbd34b2 ebbf65a c0b9609
- Added the above xkcd comic. fbd34b2 63ba50a da3ed65
- Some light modernization (#25, #28). cdec3e9 8df32fd bb7c5c9
0.6 — 2011-11-05
- When not set to strict parsing, allow a space before the time-zone specification, for greater compatibility with NSDate output (
description) and input (
- Bug fix: We no longer try to format the formatter. 83415de9f527
- Bug fix: Hours are now zero-padded correctly (#4). a5608e189ebe af0c6b397428
- Fixed many various compiler warnings. Some fixes contributed by Sparks. 8be3d6f7c6f2 78ae31de2170 68dc351e9fdb e7ea87db8621 873f499ae6db
- Now 75 times faster. 6a023812bd2b 05dc35d6b505 3b2225e0ce8c d59720ad015a 10f526956963 297b8dae4095 796be11aa596 cadf0f0c8199 61d2959c6921
- iOS users can now tell the ISO 8601 date formatter class to drop its caches (which you should do when you receive a memory warning). 2bb1725914b1
- Added a couple of command-line options to the calendar-format-unparser test tool. c644aadb2b14
- The parser test tool now displays parsed dates in GMT rather than the local time zone. 788c1455ecb1
- Added a test tool to test unparsing with the time included. a89a9a8b3d61
- You can now “make analysis” to run the Clang Static Analyzer on the date formatter. b3dd33841f42
- The test tools are now built using Clang. 0723d3aa6596
Version 0.5 was a major rewrite of much of the code, especially the unparser. Previous versions were category additions to NSCalendarDate (which is now deprecated). It's all now a single subclass of NSFormatter, and the implementation now uses NSCalendar and friends instead of the “strongly discouraged” NSCalendarDate. This means that version 0.5 and later require Mac OS X 10.4 or later. However, I have not tested it on Tiger; if it is broken on Tiger, I welcome your patch to fix it.
Version 0.4 added the ability to specify a custom time separator character instead of ':'. This works on both the parsing and unparsing directions.
Version 0.3 fixed some bugs found by Colin Barrett.
In version 0.2, I added an unparser. Now you can go back and forth between NSCalendarDate and NSString.
If you want to contribute bug-fixes or enhancements to the ISO 8601 date formatter, the easiest way to do that is to clone the Git repository on GitHub. See GitHub's help page on this topic.
This project used to be hosted in a Mercurial repository. The old Mercurial repository will never again be updated! It is frozen forever at 0.6. If you want to follow changes or contribute changes yourself, follow and/or clone the Git repo.
Thanks to Jonathan Wight for converting the old Mercurial repo to Git.
I provide the ISO 8601 date f,ormatter under a BSD license. For more information, see the file named LICENSE.txt that comes with it.