Getting human readable relative times and dates from a unix timestamp?

馋奶兔 提交于 2019-12-30 09:53:27

问题


Starting with a unix timestamp like 1290529723, how would I (assuming gmt) get the information on whether it is:

  • today (if so, what time)

  • in the last seven days (if so, which day ... mon, tues etc?)

  • older than a week (if so, how to output in dd/mm/yy format?)

I need this for a list of messages like the iPhone's Mail app, where date/times are shown relative to the current date and time, like so:

15:45
Yesterday
Sunday
Saturday
10/10/10

etc

 


回答1:


It takes a bit of fiddling to get a solution that respects the device's locale. The following method relativeStringFromDate returns a string representing the date, formatted as following:

  • just the time if the date is today, according to locale (e.g. '3:40PM' or '15:40')
  • 'Yesterday' if the date is yesterday (but will be internationalized into locale's language)
  • name of the day of the week if date is two to six days ago (e.g. 'Monday', 'Tuesday', etc, again according to locale's language)
  • just the date component if the date is over one week ago, according to locale (e.g. '1/20/2012' in US vs '20/1/2012' in Europe)

    - (NSString *)relativeStringFromDate:(NSDate *)date {
        if ([self dateIsToday:date])
            return [self dateAsStringTime:date];
        else if ([self dateIsYesterday:date])
            return [self dateAsStringDate:date];
        else if ([self dateIsTwoToSixDaysAgo:date])
            return [self dateAsStringDay:date];
        else
            return [self dateAsStringDate:date];
    }
    
    - (BOOL)date:(NSDate *)date 
            isDayWithTimeIntervalSinceNow:(NSTimeInterval)interval {
        NSDateFormatter *df = [[NSDateFormatter alloc] init];
        [df setDateFormat:@"yyyy-MM-dd"];
    
        NSDate *other_date;
        other_date = [NSDate dateWithTimeIntervalSinceNow:interval];
    
        NSString *d1, *d2;
        d1 = [df stringFromDate:date];
        d2 = [df stringFromDate:other_date];
        return [d1 isEqualToString:d2];    
    }
    
    - (BOOL)dateIsToday:(NSDate *)date {
        return [self date:date isDayWithTimeIntervalSinceNow:0];
    }
    
    - (BOOL)dateIsYesterday:(NSDate *)date {
        return [self date:date isDayWithTimeIntervalSinceNow:-86400];
    }
    
    - (BOOL)dateIsTwoToSixDaysAgo:(NSDate *)date {
        for (int i = 2; i <= 6; i += 1)
            if ([self date:date isDayWithTimeIntervalSinceNow:i*-86400])
                return YES;
        return NO;    
    }
    
    - (NSString *)dateAsStringDate:(NSDate *)date {
        NSDateFormatter *df = [[NSDateFormatter alloc] init];
        [df setDateStyle:NSDateFormatterShortStyle];
        [df setDoesRelativeDateFormatting:YES];
        NSString *str = [df stringFromDate:date];
        return str;
    }
    
    - (NSString *)dateAsStringTime:(NSDate *)date {
        NSDateFormatter *df = [[NSDateFormatter alloc] init];
        [df setTimeStyle:NSDateFormatterShortStyle];
        NSString *str = [df stringFromDate:date];
        return str;
    }
    
    - (NSString *)dateAsStringDay:(NSDate *)date {
        NSDateFormatter *df = [[NSDateFormatter alloc] init];
        [df setDateFormat:@"EEEE"];
        NSString *str_day = [df stringFromDate:date];
        return str_day;
    }
    

As mentioned in yours and Brad's answers, you can obtain an NSDate from a timestamp using NSDate's dateWithTimeIntervalSince1970.




回答2:


I made this method to change the unix time stamp into a nice readable, relative string. Probably doesn't work properly in the first few days of a new year, but hopefully you should be too hungover to notice.

-(NSString *)relativeTime:(int)datetimestamp
{
    NSDate *aDate = [NSDate dateWithTimeIntervalSince1970:datetimestamp];
    NSCalendar *calendar = [NSCalendar currentCalendar];
    unsigned int unitFlags =  NSYearCalendarUnit|NSMonthCalendarUnit|NSWeekCalendarUnit|NSWeekdayOrdinalCalendarUnit|NSWeekdayCalendarUnit|NSDayCalendarUnit|NSHourCalendarUnit|NSMinuteCalendarUnit;
    NSDateComponents *messageDateComponents = [calendar components:unitFlags fromDate:aDate];
    NSDateComponents *todayDateComponents = [calendar components:unitFlags fromDate:[NSDate date]];

    NSUInteger dayOfYearForMessage = [calendar ordinalityOfUnit:NSDayCalendarUnit inUnit:NSYearCalendarUnit forDate:aDate];
    NSUInteger dayOfYearForToday = [calendar ordinalityOfUnit:NSDayCalendarUnit inUnit:NSYearCalendarUnit forDate:[NSDate date]];


    NSString *dateString;

    if ([messageDateComponents year] == [todayDateComponents year] && 
        [messageDateComponents month] == [todayDateComponents month] &&
        [messageDateComponents day] == [todayDateComponents day]) 
    {
        dateString = [NSString stringWithFormat:@"%02d:%02d", [messageDateComponents hour], [messageDateComponents minute]];
    } else if ([messageDateComponents year] == [todayDateComponents year] && 
               dayOfYearForMessage == (dayOfYearForToday-1))
    {
        dateString = @"Yesterday";
    } else if ([messageDateComponents year] == [todayDateComponents year] &&
               dayOfYearForMessage > (dayOfYearForToday-6))
    {

        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        [dateFormatter setDateFormat:@"EEEE"];
        dateString = [dateFormatter stringFromDate:aDate];
        [dateFormatter release];

    } else {

        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        [dateFormatter setDateFormat:@"yy"];
        dateString = [NSString stringWithFormat:@"%02d/%02d/%@", [messageDateComponents day], [messageDateComponents month], [dateFormatter stringFromDate:aDate]];
        [dateFormatter release];
    }

    return dateString;
}



回答3:


I personally like the https://github.com/kevinlawler/NSDate-TimeAgo library on github. It only has two files and it's very simple to use. It also has localization if you want!




回答4:


The NSDateFormatter class has what you need. It does do "today", "tomorrow" etc. via the doesRelativeDateFormatting method.

Hope that helps someone else who lands on here and doesn't want to use an external class or creates his own.




回答5:


There is a library for that: TTTTimeIntervalFormatter in mattt's FormatterKit :)




回答6:


Convert it to an NSDate with:

+ (id)dateWithTimeIntervalSince1970:(NSTimeInterval)seconds

Then compare to other dates with:

* – compare:
* – earlierDate:
* – isEqual: (NSObject protocol)
* – laterDate:


来源:https://stackoverflow.com/questions/4260558/getting-human-readable-relative-times-and-dates-from-a-unix-timestamp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!