从unix时间戳获取人类可读的相对时间和日期?

时间:2010-11-23 20:28:19

标签: iphone objective-c ios nsdate

从像1290529723这样的unix时间戳开始,我将如何(假设gmt)获取有关它是否为的信息:

  • 今天(如果是,现在几点)

  • 过去七天(如果是,那天......周一,    这些等等?)

  • 超过一周(如果是这样,如何以dd / mm / yy输出 格式?)

我需要这个消息列表,比如iPhone的Mail应用程序,其中日期/时间相对于当前日期和时间显示,如下所示:

15:45
Yesterday
Sunday
Saturday
10/10/10

6 个答案:

答案 0 :(得分:9)

要获得一个尊重设备区域设置的解决方案,需要花点时间。以下方法relativeStringFromDate返回表示日期的字符串,格式如下:

  • 根据当地情况(例如'3:40 PM'或'15:40'),日期是今天的时间
  • '昨天'如果日期是昨天(但将国际化为当地语言)
  • 如果日期是2到6天之前的星期几的名称(例如“星期一”,“星期二”等,再次根据语言环境的语言)
  • 如果日期超过一周,则根据区域设置(例如,美国的“1/20/2012”与欧洲的'20 / 1/2012')

    - (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;
    }
    

正如您和Brad的回答中提到的,您可以使用NSDate的dateWithTimeIntervalSince1970从时间戳中获取NSDate。

答案 1 :(得分:4)

我使用此方法将unix时间戳更改为一个可读的相对字符串。可能在新的一年的前几天没有正常工作,但希望你太过于引人注意。

-(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;
}

答案 2 :(得分:4)

我个人喜欢github上的https://github.com/kevinlawler/NSDate-TimeAgo库。它只有两个文件,使用起来非常简单。如果你想要它也有本地化!

答案 3 :(得分:4)

NSDateFormatter课程符合您的要求。它确实通过didRelativeDateFormatting方法执行“今天”,“明天”等。

希望能帮助那些在这里登陆并且不想使用外部课程或创建自己的课程的其他人。

答案 4 :(得分:3)

有一个库:mattt FormatterKit中的TTTTimeIntervalFormatter:)

答案 5 :(得分:0)

使用以下命令将其转换为NSDate:

+ (id)dateWithTimeIntervalSince1970:(NSTimeInterval)seconds

然后与其他日期进行比较:

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