iOS – 友好的NSDate格式

我需要在我的应用中向用户显示post的date,现在我以这种格式:“5月25日星期五”。 我将如何格式化NSDate来阅读“2小时前”的内容? 使其更加用户友好。

NSDateFormatter不能做这样的事情; 你将需要build立自己的规则。 我猜想是这样的:

 - (NSString *)formattedDate:(NSDate *)date { NSTimeInterval timeSinceDate = [[NSDate date] timeIntervalSinceDate:date]; // print up to 24 hours as a relative offset if(timeSinceDate < 24.0 * 60.0 * 60.0) { NSUInteger hoursSinceDate = (NSUInteger)(timeSinceDate / (60.0 * 60.0)); switch(hoursSinceDate) { default: return [NSString stringWithFormat:@"%d hours ago", hoursSinceDate]; case 1: return @"1 hour ago"; case 0: NSUInteger minutesSinceDate = (NSUInteger)(timeSinceDate / 60.0); /* etc, etc */ break; } } else { /* normal NSDateFormatter stuff here */ } } 

所以这是在“x分钟前”或“x小时前”打印最多24小时,通常是一天。

看看FormaterKit https://github.com/mattt/FormatterKit

由mattt创build谁也创build了AFNetworking。

我希望像Facebook这样的date格式为他们的移动应用程序,所以我掀起了这个NSDate类别 – 希望它是有用的人(这种东西应该真的在一个标准库!):)

https://github.com/nikilster/NSDate-Time-Ago

SEHumanizedTimeDiff也支持多种语言,如果这对你来说是个问题:

https://github.com/sarperdag/SEHumanizedTimeDiff

有大约一百万种方法可以做到这一点,但这里有一个很快的方法:

 NSString* hoursAgo = [NSString stringWithFormat:@"%.0lf hours ago", fabs([date timeIntervalSinceNow] / 3600.0)] 

当然,这并不能检查date是否来自过去,除了几小时之外什么也不做,但是,你可能会明白这一点。

timeIntervalSinceNow返回timeIntervalSinceNow定date以来已过去多less秒,其中正数是将来的date,负数是过去的date。 因此,我们得到了多less秒钟,在一小时内将它除以3600秒,以计算已经过去的小时,然后将其绝对值置于“n小时前”的string中。

这是一个非常好的答案,这将在自1970年1月1日以来的几秒钟内完成,并返回一个很好的格式化string,例如“3分钟前”。 只需要用你的date对象调用它就可以了:

 [timeAgoFromUnixTime:[myDateObject timeIntervalSince1970]]; + (NSString *)timeAgoFromUnixTime:(double)seconds { double difference = [[NSDate date] timeIntervalSince1970] - seconds; NSMutableArray *periods = [NSMutableArray arrayWithObjects:@"second", @"minute", @"hour", @"day", @"week", @"month", @"year", @"decade", nil]; NSArray *lengths = [NSArray arrayWithObjects:@60, @60, @24, @7, @4.35, @12, @10, nil]; int j = 0; for(j=0; difference >= [[lengths objectAtIndex:j] doubleValue]; j++) { difference /= [[lengths objectAtIndex:j] doubleValue]; } difference = roundl(difference); if(difference != 1) { [periods insertObject:[[periods objectAtIndex:j] stringByAppendingString:@"s"] atIndex:j]; } return [NSString stringWithFormat:@"%li %@%@", (long)difference, [periods objectAtIndex:j], @" ago"]; } 

在更新版本的iOS中,因为这个问题被问到, NSDateFormatter已经添加了这个能力。 现在可以使用doesRelativeDateFormatting属性来完成它了。

 +(NSString*)HourCalculation:(NSString*)PostDate { NSLog(@"postdate=%@",PostDate); // PostDate=@"2014-04-02 01:31:04"; NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; [dateFormat setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; NSTimeZone *gmt = [NSTimeZone timeZoneWithAbbreviation:@"GMT"]; [dateFormat setTimeZone:gmt]; NSDate *ExpDate = [dateFormat dateFromString:PostDate]; NSLog(@"expdate=%@",ExpDate); NSLog(@"expdate=%@",[NSDate date ]); NSCalendar *calendar = [NSCalendar currentCalendar]; NSDateComponents *components = [calendar components:(NSDayCalendarUnit|NSWeekCalendarUnit|NSMonthCalendarUnit|NSYearCalendarUnit|NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit) fromDate:ExpDate toDate:[NSDate date] options:0]; // NSLog(@"year=%d",components.year); // // NSLog(@"month=%d",components.month); // // NSLog(@"week=%d",components.week); // // NSLog(@"day=%d",components.day); // // NSLog(@"hour=%d",components.hour); // // NSLog(@"min=%d",components.minute); // // NSLog(@"sce=%d",components.second); // NSString *time; if(components.year!=0) { if(components.year==1) { time=[NSString stringWithFormat:@"%ld year",(long)components.year]; } else{ time=[NSString stringWithFormat:@"%ld years",(long)components.year]; } } else if(components.month!=0) { if(components.month==1) { time=[NSString stringWithFormat:@"%ld month",(long)components.month]; } else{ time=[NSString stringWithFormat:@"%ld months",(long)components.month]; } // NSLog(@"%@",time); } else if(components.week!=0) { if(components.week==1) { time=[NSString stringWithFormat:@"%ld week",(long)components.week]; } else{ time=[NSString stringWithFormat:@"%ld weeks",(long)components.week]; } // NSLog(@"%@",time); } else if(components.day!=0) { if(components.day==1) { time=[NSString stringWithFormat:@"%ld day",(long)components.day]; } else{ time=[NSString stringWithFormat:@"%ld days",(long)components.day]; } } else if(components.hour!=0) { if(components.hour==1) { time=[NSString stringWithFormat:@"%ld hour",(long)components.hour]; } else{ time=[NSString stringWithFormat:@"%ld hours",(long)components.hour]; } } else if(components.minute!=0) { if(components.minute==1) { time=[NSString stringWithFormat:@"%ld min",(long)components.minute]; } else{ time=[NSString stringWithFormat:@"%ld mins",(long)components.minute]; } // NSLog(@"time=%@",time); } else if(components.second>=0){ // NSLog(@"postdate=%@",PostDate); // NSLog(@"expdate=%@",[NSDate date ]); if(components.second==0) { time=[NSString stringWithFormat:@"1 sec"]; } else{ time=[NSString stringWithFormat:@"%ld secs",(long)components.second]; } } return [NSString stringWithFormat:@"%@ ago",time]; } 

这段代码会在2秒前的————秒中显示你的时间———— min像2分钟前的那样——— —像2小时前的小时————像2天前的那样————周像2个星期前——– —-像2个月前的月份最后….像2年前的那样:)试试这个

添加到解决scheme尝试这个更简化的方法

  NSDateComponents *today = [[NSCalendar currentCalendar] components:NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitSecond fromDate:passed toDate:[NSDate date] options:0]; NSTimeInterval interval = [[NSDate date] timeIntervalSinceDate:date]; if (interval < 60) timestampString = [NSString stringWithFormat:@"%d seconds ago" ,today.second]; else if (interval < 60 * 60) timestampString = [NSString stringWithFormat:@"%d minutes ago" ,today.minute]; else if (interval < 60 * 60 * 24) timestampString = [NSString stringWithFormat:@"%d hours ago" ,today.hour]; else timestampString = [NSString stringWithFormat:@"%d days ago" ,today.day];