There is a property in NSDateFormatter – “doesRelativeDateFormatting”. It appears only in 10.6/iOS4.0 and later but it will format a date into a relative date in the correct locale.
From Apple’s Documentation:
If a date formatter uses relative date
formatting, where possible it replaces
the date component of its output with
a phrase—such as “today” or
“tomorrow”—that indicates a relative
date. The available phrases depend on
the locale for the date formatter;
whereas, for dates in the future,
English may only allow “tomorrow,”
French may allow “the day after the
day after tomorrow,” as illustrated in
the following example.
Code
The following is code that will print out a good number of the relative strings for a given locale.
NSLocale *locale = [NSLocale currentLocale];
// NSLocale *locale = [[[NSLocale alloc] initWithLocaleIdentifier:@"fr_FR"] autorelease];
NSDateFormatter *relativeDateFormatter = [[NSDateFormatter alloc] init];
[relativeDateFormatter setTimeStyle:NSDateFormatterNoStyle];
[relativeDateFormatter setDateStyle:NSDateFormatterMediumStyle];
[relativeDateFormatter setDoesRelativeDateFormatting:YES];
[relativeDateFormatter setLocale:locale];
NSDateFormatter *normalDateFormatter = [[NSDateFormatter alloc] init];
[normalDateFormatter setTimeStyle:NSDateFormatterNoStyle];
[normalDateFormatter setDateStyle:NSDateFormatterMediumStyle];
[normalDateFormatter setDoesRelativeDateFormatting:NO];
[normalDateFormatter setLocale:locale];
NSString * lastUniqueString = nil;
for ( NSTimeInterval timeInterval = -60*60*24*400; timeInterval < 60*60*24*400; timeInterval += 60.0*60.0*24.0 )
{
NSDate * date = [NSDate dateWithTimeIntervalSinceNow:timeInterval];
NSString * relativeFormattedString = [relativeDateFormatter stringForObjectValue:date];
NSString * formattedString = [normalDateFormatter stringForObjectValue:date];
if ( [relativeFormattedString isEqualToString:lastUniqueString] || [relativeFormattedString isEqualToString:formattedString] )
continue;
NSLog( @"%@", relativeFormattedString );
lastUniqueString = relativeFormattedString;
}
Notes:
- A locale is not required
- There are
not that many substitutions for
English. At the time of writing there
are: “Yesterday, Today, Tomorrow”.
Apple may include more in the future. - It’s fun to change the locale and see
what is available in other languages
(French has a few more than English,
for example) - If on iOS, you might want to subscribe to UIApplicationSignificantTimeChangeNotification
Interface Builder
You can set the “doesRelativeDateFormatting” property in Interface Builder:
- Select your NSDateFormatter and
choose the “Identity Inspector” tab
of the Inspector Palette (the last
one [command-6]). - Under the sub-section named “User
Defined Runtime Attributes”, you can
add your own value for a key on the selected object (in this case, your NSDateFormatter instance). Add
“doesRelativeDateFormatting”, choose
a “Boolean” type, and make sure it’s
checked. - Remember: It may look like it didn’t work at all, but that might because there are only a few substituted values for your locale. Try at least a date for Yesterday, Today, and Tomorrow before you decide if it’s not set up right.