How to Format Date in to String Like as "One Days Ago","Minutes Ago" in IOS?

user4202773 picture user4202773 · Dec 17, 2014 · Viewed 14.3k times · Source

I make an Application that contains JSON parse data here is my JSON parse data containing a Date like "2014-12-02 08:00:42" then I convert this Date into following format "12 FEB 2014" like as

NSDateFormatter * dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:@"yyyy-MM-dd hh:mm:ss"];
NSString *date=[dict valueForKey:@"post_date"];
NSDate * dateNotFormatted = [dateFormatter dateFromString:date];
[dateFormatter setDateFormat:@"d MMM YYYY"];
NSString * dateFormatted = [dateFormatter stringFromDate:dateNotFormatted];
cell.timeLabel.text=[dateFormatted uppercaseString];

It is working fine but now I want to convert this dateFormatted string into "One Day Ago","Minutes Ago". I know that this question is asked many times before.

Answer

jDutton picture jDutton · Oct 13, 2015

As of iOS 8, you can get a lot of help (including localization) by using NSDateComponentsFormatter. Note: you can easily change how much granularity the string shows by changing the allowedUnits on the components formatter if you want to return a string like "2 days, 3 hours, 5 minutes ago".

Swift 4:

func timeAgoStringFromDate(date: Date) -> String? {
    let formatter = DateComponentsFormatter()
    formatter.unitsStyle = .full

    let now = Date()

    let calendar = NSCalendar.current
    let components1: Set<Calendar.Component> = [.year, .month, .weekOfMonth, .day, .hour, .minute, .second]
    let components = calendar.dateComponents(components1, from: date, to: now)

    if components.year ?? 0 > 0 {
        formatter.allowedUnits = .year
    } else if components.month ?? 0 > 0 {
        formatter.allowedUnits = .month
    } else if components.weekOfMonth ?? 0 > 0 {
        formatter.allowedUnits = .weekOfMonth
    } else if components.day ?? 0 > 0 {
        formatter.allowedUnits = .day
    } else if components.hour ?? 0 > 0 {
        formatter.allowedUnits = [.hour]
    } else if components.minute ?? 0 > 0 {
        formatter.allowedUnits = .minute
    } else {
        formatter.allowedUnits = .second
    }

    let formatString = NSLocalizedString("%@ left", comment: "Used to say how much time has passed. e.g. '2 hours ago'")

    guard let timeString = formatter.string(for: components) else {
        return nil
    }
    return String(format: formatString, timeString)
}

let str = timeAgoStringFromDate(date: Date().addingTimeInterval(-11000))
// Result: "3 hours, 3 minutes left"

Swift:

class func timeAgoStringFromDate(date: NSDate) -> NSString? {
    let formatter = NSDateComponentsFormatter()
    formatter.unitsStyle = .Full

    let now = NSDate()

    let calendar = NSCalendar.currentCalendar()
    let components = calendar.components([NSCalendarUnit.Year, .Month, .WeekOfMonth, .Day, .Hour, .Minute, .Second],
        fromDate: date,
        toDate: now,
        options:NSCalendarOptions(rawValue: 0))

    if components.year > 0 {
        formatter.allowedUnits = .Year
    } else if components.month > 0 {
        formatter.allowedUnits = .Month
    } else if components.weekOfMonth > 0 {
        formatter.allowedUnits = .WeekOfMonth
    } else if components.day > 0 {
        formatter.allowedUnits = .Day
    } else if components.hour > 0 {
        formatter.allowedUnits = .Hour
    } else if components.minute > 0 {
        formatter.allowedUnits = .Minute
    } else {
        formatter.allowedUnits = .Second
    }

    let formatString = NSLocalizedString("%@ ago", comment: "Used to say how much time has passed. e.g. '2 hours ago'")

    guard let timeString = formatter.stringFromDateComponents(components) else {
        return nil
    }
    return String(format: formatString, timeString)
}

Objective-C:

+ (NSString *)timeAgoStringFromDate:(NSDate *)date {
    NSDateComponentsFormatter *formatter = [[NSDateComponentsFormatter alloc] init];
    formatter.unitsStyle = NSDateComponentsFormatterUnitsStyleFull;

    NSDate *now = [NSDate date];

    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDateComponents *components = [calendar components:(NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitWeekOfMonth|NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitSecond)
                                               fromDate:date
                                                 toDate:now
                                                options:0];

    if (components.year > 0) {
        formatter.allowedUnits = NSCalendarUnitYear;
    } else if (components.month > 0) {
        formatter.allowedUnits = NSCalendarUnitMonth;
    } else if (components.weekOfMonth > 0) {
        formatter.allowedUnits = NSCalendarUnitWeekOfMonth;
    } else if (components.day > 0) {
        formatter.allowedUnits = NSCalendarUnitDay;
    } else if (components.hour > 0) {
        formatter.allowedUnits = NSCalendarUnitHour;
    } else if (components.minute > 0) {
        formatter.allowedUnits = NSCalendarUnitMinute;
    } else {
        formatter.allowedUnits = NSCalendarUnitSecond;
    }

    NSString *formatString = NSLocalizedString(@"%@ ago", @"Used to say how much time has passed. e.g. '2 hours ago'");

    return [NSString stringWithFormat:formatString, [formatter stringFromDateComponents:components]];
}