In The Hit List for Mac, we’ve long supported a wide range of date formats when typing in a task’s start or due date. Another app I’m fond of — Fantastical — takes this even further, doing its best to interpret all the details of a calendar event from whatever you type. What if you wanted to achieve this in your own app?
On the Mac, we’ve long had +[NSDate dateWithNaturalLanguageString:], but Apple have recently deprecated it (seems they don’t like the unpredictability and lack of localisation), and it’s never been available on iOS. So what to replace it with?
Usually, NSDateFormatter is our go-to-class for date formatting. Again on the Mac, there’s -initWithDateFormat:allowNaturalLanguage:, but it’s also been deprecated now.
Casting around, NSDateFormatter.lenient looks quite promising. It’s available on both iOS and OS X, albeit very recently (iOS 8 and OS X 10.10 according to the docs). My experiments with it have been very disappointing though.
As far as I can see, it doesn’t support anything like the range of the older APIs. Indeed as best I can tell the leniency only comes into play as far as separator characters are concerned. So for example, if dates are expected to be in the format YYYY/MM/DD, then strings of the form YYYY-MM-DD will also be accepted. But that’s about it.
You want the flexibility to leave out specifying the year, or specify months by name or number? Forget it. Maybe there’s something I’m missing here. If so, please let me know!
But then Warren suggested a technique I’d forgotten about: NSDataDetector. Usually, data detectors are used to scan over bodies of text looking for things that could be links, locations, dates etc. Well you can point a data detector at a simple bit of user-entered text to much the same effect, asking it just to scan for dates:
It’s not perfect but does a pretty good job, and runs under both OS X and iOS.