iPhone: Convert date string to a relative time stamp

后端 未结 11 977
醉梦人生
醉梦人生 2020-11-27 09:30

I\'ve got a timestamp as a string like:

Thu, 21 May 09 19:10:09 -0700

and I\'d like to convert it to a relative time stamp like

相关标签:
11条回答
  • 2020-11-27 10:18

    My solution:

    - (NSString *) dateToName:(NSDate*)dt withSec:(BOOL)sec {
    
        NSLocale *locale = [NSLocale currentLocale];
        NSTimeInterval tI = [[NSDate date] timeIntervalSinceDate:dt];
        if (tI < 60) {
          if (sec == NO) {
               return NSLocalizedString(@"Just Now", @"");
           }
           return [NSString stringWithFormat:
                     NSLocalizedString(@"%d seconds ago", @""),(int)tI];
         }
         if (tI < 3600) {
           return [NSString stringWithFormat:
                     NSLocalizedString(@"%d minutes ago", @""),(int)(tI/60)];
         }
         if (tI < 86400) {
          return [NSString stringWithFormat:
                     NSLocalizedString(@"%d hours ago", @""),(int)tI/3600];
         }
    
         NSDateFormatter *relativeDateFormatter = [[NSDateFormatter alloc] init];
         [relativeDateFormatter setTimeStyle:NSDateFormatterNoStyle];
         [relativeDateFormatter setDateStyle:NSDateFormatterMediumStyle];
         [relativeDateFormatter setDoesRelativeDateFormatting:YES];
         [relativeDateFormatter setLocale:locale];
    
         NSString * relativeFormattedString = 
                [relativeDateFormatter stringForObjectValue:dt];
         return relativeFormattedString;
    }
    
    0 讨论(0)
  • 2020-11-27 10:24

    In the interest of completeness, based on a @Gilean's answer, here's the complete code for a simple category on NSDate that mimics rails' nifty date helpers. For a refresher on categories, these are instance methods that you would call on NSDate objects. So, if I have an NSDate that represents yesterday, [myDate distanceOfTimeInWordsToNow] => "1 day".

    Hope it's useful!

    @interface NSDate (NSDate_Relativity)
    
    -(NSString *)distanceOfTimeInWordsSinceDate:(NSDate *)aDate;
    -(NSString *)distanceOfTimeInWordsToNow;
    
    @end
    
    
    
    @implementation NSDate (NSDate_Relativity)
    
    
    -(NSString *)distanceOfTimeInWordsToNow {
        return [self distanceOfTimeInWordsSinceDate:[NSDate date]];
    
    }
    
    -(NSString *)distanceOfTimeInWordsSinceDate:(NSDate *)aDate {
        double interval = [self timeIntervalSinceDate:aDate];
    
        NSString *timeUnit;
        int timeValue;
    
        if (interval < 0) {
            interval = interval * -1;        
        }
    
        if (interval< 60) {
            return @"seconds";
    
        } else if (interval< 3600) { // minutes
    
            timeValue = round(interval / 60);
    
            if (timeValue == 1) {
                timeUnit = @"minute";
    
            } else {
                timeUnit = @"minutes";
    
            }
    
    
        } else if (interval< 86400) {
            timeValue = round(interval / 60 / 60);
    
            if (timeValue == 1) {
                timeUnit = @"hour";
    
            } else {
                timeUnit = @"hours";
            }
    
    
        } else if (interval< 2629743) {
            int days = round(interval / 60 / 60 / 24);
    
            if (days < 7) {
    
                timeValue = days;
    
                if (timeValue == 1) {
                    timeUnit = @"day";
                } else {
                    timeUnit = @"days";
                }
    
            } else if (days < 30) {
                int weeks = days / 7;
    
                timeValue = weeks;
    
                if (timeValue == 1) {
                    timeUnit = @"week";
                } else {
                    timeUnit = @"weeks";
                }
    
    
            } else if (days < 365) {
    
                int months = days / 30;
                timeValue = months;
    
                if (timeValue == 1) {
                    timeUnit = @"month";
                } else {
                    timeUnit = @"months";
                }
    
            } else if (days < 30000) { // this is roughly 82 years. After that, we'll say 'forever'
                int years = days / 365;
                timeValue = years;
    
                if (timeValue == 1) {
                    timeUnit = @"year";
                } else {
                    timeUnit = @"years";
                }
    
            } else {
                return @"forever ago";
            }
        }
    
        return [NSString stringWithFormat:@"%d %@", timeValue, timeUnit];
    
    }
    
    @end
    
    0 讨论(0)
  • 2020-11-27 10:29

    In Swift

    Usage:

    let time = NSDate(timeIntervalSince1970: timestamp).timeIntervalSinceNow
    let relativeTimeString = NSDate.relativeTimeInString(time)
    println(relativeTimeString)
    

    Extension:

    extension NSDate {
        class func relativeTimeInString(value: NSTimeInterval) -> String {
            func getTimeData(value: NSTimeInterval) -> (count: Int, suffix: String) {
                let count = Int(floor(value))
                let suffix = count != 1 ? "s" : ""
                return (count: count, suffix: suffix)
            }
    
            let value = -value
            switch value {
                case 0...15: return "just now"
    
                case 0..<60:
                    let timeData = getTimeData(value)
                    return "\(timeData.count) second\(timeData.suffix) ago"
    
                case 0..<3600:
                    let timeData = getTimeData(value/60)
                    return "\(timeData.count) minute\(timeData.suffix) ago"
    
                case 0..<86400:
                    let timeData = getTimeData(value/3600)
                    return "\(timeData.count) hour\(timeData.suffix) ago"
    
                case 0..<604800:
                    let timeData = getTimeData(value/86400)
                    return "\(timeData.count) day\(timeData.suffix) ago"
    
                default:
                    let timeData = getTimeData(value/604800)
                    return "\(timeData.count) week\(timeData.suffix) ago"
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-27 10:31

    I saw that there were several time ago functions in snippets of code on Stack Overflow and I wanted one that really gave the clearest sense of the time (since some action occurred). To me this means "time ago" style for short time intervals (5 min ago, 2 hours ago) and specific dates for longer time periods (April 15, 2011 instead of 2 years ago). Basically I thought Facebook did a really good job at this and I wanted to just go by their example (as I'm sure they out a lot of thought into this and it is very easy and clear to understand from the consumer perspective).

    After a long time of googling I was pretty surprised to see that no one had implemented this as far as I could tell. Decided that I wanted it bad enough to spend the time writing and thought that I would share.

    Hope you enjoy :)

    Get the code here: https://github.com/nikilster/NSDate-Time-Ago

    0 讨论(0)
  • 2020-11-27 10:33

    Not sure why this isnt in cocoa-touch, i nice standard way of doing this would be great.

    Set up some types to keep the data in, it will make it easier if you ever ned to localise it a bit more. (obviously expand if you need more time periods)

    typedef struct DayHours {
        int Days;
        double Hours;
    } DayHours;
    
    
    + (DayHours) getHourBasedTimeInterval:(double) hourBased withHoursPerDay:(double) hpd
    {
        int NumberOfDays = (int)(fabs(hourBased) / hpd);
        float hoursegment = fabs(hourBased) - (NumberOfDays * hpd);
        DayHours dh;
        dh.Days = NumberOfDays;
        dh.Hours = hoursegment;
        return dh;
    }
    

    NOTE: I"m using an hour based calculation , as that is what my data is in. NSTimeInterval is second based. I also had to convert between the two.

    0 讨论(0)
提交回复
热议问题