6

My app presenting a list of messages, each has a creation date.

I don't want to just show the date but to show different formats according to how much time passed from the creation date.

for example, this is how I create the date string from the date:

NSDate *date = someMessage.creationDate;
NSTimeInterval timePassed = [[NSDate date] timeIntervalSinceDate:date];

if (timePassed < 60 ) { // less then one minute
  return @"now"
} else if (timePassed < 3600) { // less then one hour
  NSInteger minutes = (NSInteger) floor(timePassed / 60.0);
  return [NSString stringWithFormat:@"%d minutes ago", minutes];
}

so now I want to add the following cases:

else if ("timePassed < 24 hours ago and within the same calendar day")
   // do something
} else if ("timePassed > 24 hours, or within previous calendar day") {
   // do something else
}

but not sure how to do it, any help will be appreciated

Mario
  • 2,431
  • 6
  • 27
  • 34

2 Answers2

7

Here's a simple category on NSDate that adds useful date comparison methods:

#ifndef SecondsPerDay
  #define SecondsPerDay 86400
#endif

@interface NSDate (Additions)

/**
 *  This method returns the number of days between this date and the given date.
 */
- (NSUInteger)daysBetween:(NSDate *)date;

/**
 *  This method compares the dates without time components.
 */
- (NSComparisonResult)timelessCompare:(NSDate *)date;

/*  
 * This method returns a new date with the time set to 12:00 AM midnight local time.
 */
- (NSDate *)dateWithoutTimeComponents;

@end

@implementation NSDate (Additions)

- (NSUInteger)daysBetween:(NSDate *)date
{
  NSDate *dt1 = [self dateWithoutTimeComponents];
  NSDate *dt2 = [date dateWithoutTimeComponents];
  return ABS([dt1 timeIntervalSinceDate:dt2] / SecondsPerDay);
}

- (NSComparisonResult)timelessCompare:(NSDate *)date
{
  NSDate *dt1 = [self dateWithoutTimeComponents];
  NSDate *dt2 = [date dateWithoutTimeComponents];
  return [dt1 compare:dt2];
}

- (NSDate *)dateWithoutTimeComponents
{
  NSCalendar *calendar = [NSCalendar currentCalendar];
  NSDateComponents *components = [calendar components:NSYearCalendarUnit  |
                                                      NSMonthCalendarUnit |
                                                      NSDayCalendarUnit
                                             fromDate:self];
  return [calendar dateFromComponents:components];
}

@end

Example Use:

NSDate *currentDate = [NSDate date];
NSDate *distantPastDate = [NSDate distantPast];

NSComparisonResult *result = [currentDate timelessCompare:distantPastDate];
// result will equal NSOrderedDescending

Need to know a more detailed difference in time?

Do you need to know the difference between two dates down to the second? Use timeIntervalSinceDate: which comes standard on NSDate.

JRG-Developer
  • 12,454
  • 8
  • 55
  • 81
1

You are going to want to look at this answer.

Namely:

NSDateComponents *components = [[NSCalendar currentCalendar] components:NSCalendarUnitYear fromDate:yourDate];

NSUInteger year = [components year];
NSUInteger dayOfYear = [[NSCalendar currentCalendar] ordinalityOfUnit:NSDayCalendarUnit inUnit:NSYearCalendarUnit forDate:yourDate];

Check that day attribute for both NSDates, then you will know if they were on the same calandar day. As for the 24 hours or less/more, you can take one date and use the function timeIntervalSinceDate: and see if that is more/less than 86400 (numver of seconds in a day).

EDIT: updated to be more a more specific check for year and dayOfYear.

Community
  • 1
  • 1
Putz1103
  • 6,211
  • 1
  • 18
  • 25
  • 1
    This is not quite correct. Unless I am mistaken, your method gives the day of the month. So you would get for example 20 for both January 20 and August 20. – Martin R Jan 26 '14 at 14:56
  • @Martin Thanks, I was thinking very narrow minded. Corrected. – Putz1103 Jan 26 '14 at 15:01