Search code examples
iosnsdatensdateformatterrelative-date

Short formatted relative time in iOS?


I'm using the NSDate-TimeAgo library to format relative time in my iOS application. It displays the relative time of each post in its cell header, as so:

NSDateFormatter *df = [[NSDateFormatter alloc] init];
        [df setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
        NSDate *myDate = [df dateFromString: self.datePostedString];
        UILabel *time = [[UILabel alloc]initWithFrame:CGRectMake(230,0,80,50)];
        DDLogVerbose(@"Output is: \"%@\"", [myDate dateTimeAgo]);
        time.text = [myDate dateTimeAgo];
        time.textAlignment = NSTextAlignmentRight;
        [time setFont:[UIFont systemFontOfSize:10]];

However, this library gives me strings that I find are too long. A post in the last minute would be labeled as "a minute ago". I'd like it to be shorter, such as "1m".

Is this possible to do without having to modify the library, or is there an alternative that already does this?


Solution

  • You can not achieve this without changing the third-party class. In your situation, NSDate-TimeAgo library is too powerful for you. You even don't need any 'ago' result. So, personally I suggest you to convert time string on your own code, something like (just an example, maybe there are some performance issues here, you can use Time Profile to test it):

    + (NSString *)stringForDisplayFromDate:(NSDate *)date
    {
        if (!date) {
            return nil;
        }
    
        NSDate *currentDate = [NSDate date];
        NSCalendar *calendar = [NSCalendar currentCalendar];
        NSDateComponents *components = [calendar components:(kCFCalendarUnitYear
                                                         |kCFCalendarUnitMonth
                                                         |kCFCalendarUnitWeek
                                                         |kCFCalendarUnitDay
                                                         |kCFCalendarUnitHour
                                                         |kCFCalendarUnitMinute)
                                               fromDate:date
                                                 toDate:currentDate
                                                options:0];
        if (components.year == 0) {
            // same year
            if (components.month == 0) {
                // same month
                if (components.week == 0) {
                    // same week
                    if (components.day == 0) {
                        // same day
                        if (components.hour == 0) {
                            // same hour
                            if (components.minute < 10) {
                                // in 10 mins
                                return @"now";
                            } else {
                                // 10 mins age
                                return [NSString stringWithFormat:@"%dm", (int)(components.minute/10)*10];
                            }
                        } else {
                            // different hour
                            return [NSString stringWithFormat:@"%dh", components.hour];
                        }
                    } else {
                        // different day
                        return [NSString stringWithFormat:@"%dd", components.day];
                    }    
                } else {
                    // different week
                    return [NSString stringWithFormat:@"%dW", components.week];
                }
            } else {
                // different month
                return [NSString stringWithFormat:@"%dM", components.month];
            }
        } else {
            // different year
            return [NSString stringWithFormat:@"%dY", components.year];
        }
    
        return [self stringForDisplayFromDate:date prefixed:NO];
    }