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

问题描述:

与UNIX时间戳一样1290529723,我将如何(假设GMT)得到它是否是信息开始:​​在过去七天今天从unix时间戳中获取人类可读的相对时间和日期?

  • (如果是的话,什么时间)

  • (如果是的话,这一天......周一,周二 等?)不到一个星期

  • 以上(如果是这样,如何在DD/MM/YY 格式输出?)

我需要这个像iPhone的邮件应用程序,其中的日期/时间显示相对于当前日期和时间,像这样的邮件列表:

15:45 
Yesterday 
Sunday 
Saturday 
10/10/10 

我做了这个方法,把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

这是一个很好的答案,但事实上,没有公共的API调用(正如在mail.app中所做的那样)是不可信的 – lol 2012-01-23 05:01:09

将它转换用一个NSDate:

+ (id)dateWithTimeIntervalSince1970:(NSTimeInterval)seconds 

然后与其他日期比较有:

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

另请参见NSDateComponents(提取时间)和NSDateFormatter(将其转换为字符串)。请记住,“当前”日历不一定是你想要的; iPhone上有4种可用的格里历日历,但年份编号不同。做一些测试并决定你想要什么;它可能是`[[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease]`。 – 2010-11-23 22:26:38

获取尊重设备区域设置的解决方案需要一点小窍门。以下方法relativeStringFromDate返回表示日期的字符串,格式为以下:

  • 只是如果日期是今天,根据区域(例如,“3:40 PM”或'15:40' )的时间
  • '昨天'如果日期是昨天(但将被国际化为本地语言)
  • 如果日期是2至6天前,则为星期几的名称(例如,'星期一','星期二'等,再次根据语言环境的语言)
  • 只是日期部分,如果日期超过一周前,根据语言环境(例如'2012年1月20日'与'20/1/2012'欧元OPE)

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

正如你和布拉德的答案中提到,您可以使用的NSDate的dateWithTimeIntervalSince1970时间戳获得一个NSDate。

+0

谢谢你 - 伟大的实现 – Andy 2014-03-11 19:55:20

+0

谢谢Amos,这是一个非常有用的一段代码。 – mszaro 2014-11-11 02:18:45

有该库:TTTTimeIntervalFormatter在mattt的FormatterKit :)

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

NSDateFormatter类有你所需要的。它通过doRelativeDateFormatting方法做“今天”,“明天”等。

希望能帮助别人在这里降落,不想使用外部课堂或创建自己的课堂。