Using setDoesRelativeDateFormatting: YES and setDateFormat: with NSDateFormatter

NSDateFormatter has a lovely support for producing relative dates such as "Today", "Tomorrow", "Yesterday" when these are supported by the current language. A great advantage is that all of these are localised for you already – you don't need to translate the strings.

You can turn on this functionality with:

[dateFormatter setDoesRelativeDateFormatting: YES];

The down side is that this only seems to work for an instance that is using one of the predefined formats, such as:

[dateFormatter setDateStyle: NSDateFormatterShortStyle];

If you set up the date formatter to use a custom format, like this:

[dateFormatter setDateStyle: @"EEEE"];

Then when you call:

[dateFormatter stringFromDate: date];

… you will just get back an empty string.

I'd like to be able to get relative strings when possible, and use my own custom format when it is not.

How does this work?

It maintains two date formatters using an (arbitrary) standard format. They format identically except that one will provide relative date strings and the other will not.

By formatting a given date with both formatters, it is possible to see if the relative date formatter is giving a special relative date. There is a special relative date when the two formatters give different results.

If there is a special relative date string, that special relative date string is returned.

If there is not a special relative date string, the original formatter is used as a fallback and the format settings you have defined on it are used.

A Limitation…

The implementation does not handle time components that you may have placed in to your format string. When a relative date string is available, your format sting is ignored and you get the relative date string.

Email codedump link for Using setDoesRelativeDateFormatting: YES and setDateFormat: with NSDateFormatter