In my current project, I needed to know if a given NSDate was today, yesterday or earlier. Simple task, I thought. Until I looked at the documentation for NSCalendar, NSDateComponents and NSDate. While these are extremely powerful, I am not proud of the code I’ve written. It should be easier.
Anyway, the code below will take a date and return a formatted version relative from today:
- Today, 11h35
- Yesterday, 8h27
- January 12, 22h27
- (NSString *) formattedDateRelativeToNow:(NSDate *)date
{
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *newsComponents = [gregorian components:(NSYearCalendarUnit | NSDayCalendarUnit | NSMonthCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit)
fromDate:date];
[newsComponents setHour:0];
[newsComponents setMinute:0];
[newsComponents setSecond:0];
NSDate *dateAtMidnight = [gregorian dateFromComponents:newsComponents];
NSInteger dayDiff = [[gregorian components:(NSDayCalendarUnit)
fromDate:dateAtMidnight
toDate:[NSDate date]
options:0]
day];
if (dayDiff == 0) {
[dateFormatter setDateFormat:@"'today, 'H'h'mm"];
} else {
if (dayDiff == 1) {
[dateFormatter setDateFormat:@"'yesterday, 'H'h'mm"];
} else {
[dateFormatter setDateFormat:@"MMMM d, H'h'mm"];
}
}
[gregorian release];
return [dateFormatter stringFromDate:date];
}
After having written this code, I found these similar posts on the subject (look at the answers given by mmalc – Malcolm Crawford):
Hint: if you display relative dates in your project, on the iPhone you should handle the « UIApplicationSignificantTimeChangeNotification » notification.
Update: I knew there was an easier way. Solution by Nicolas Seriot:
- (NSString *) formattedDateRelativeToNow2:(NSDate *)date {
NSDateFormatter *mdf = [[NSDateFormatter alloc] init];
[mdf setDateFormat:@"yyyy-MM-dd"];
NSDate *midnight = [mdf dateFromString:[mdf stringFromDate:date]];
[mdf release];
NSUInteger dayDiff = (int)[midnight timeIntervalSinceNow] / (60*60*24);
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
switch(dayDiff) {
case 0:
[dateFormatter setDateFormat:@"'today, 'H'h'mm"]; break;
case -1:
[dateFormatter setDateFormat:@"'yesterday, 'H'h'mm"]; break;
default:
[dateFormatter setDateFormat:@"MMMM d, H'h'mm"];
}
return [dateFormatter stringFromDate:date];
}