【发布时间】:2012-04-21 23:38:08
【问题描述】:
我需要在我的应用程序中向用户显示帖子的日期,现在我以这种格式执行此操作:“5 月 25 日,星期五”。我将如何格式化 NSDate 以读取“2 小时前”之类的内容?使其更加用户友好。
【问题讨论】:
-
检查this answer 有示例链接。
标签: ios date nsdate nsdateformatter date-format
我需要在我的应用程序中向用户显示帖子的日期,现在我以这种格式执行此操作:“5 月 25 日,星期五”。我将如何格式化 NSDate 以读取“2 小时前”之类的内容?使其更加用户友好。
【问题讨论】:
标签: ios date nsdate nsdateformatter date-format
看看 FormaterKit https://github.com/mattt/FormatterKit
由同样创建了 AFNetworking 的 mattt 创建。
【讨论】:
NSDateFormatter 不能那样做;你需要建立自己的规则。我猜是这样的:
- (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 */
}
}
也就是说,从日期开始最多 24 小时打印“x 分钟前”或“x 小时前”,通常是一天。
【讨论】:
我想要 Facebook 为他们的移动应用程序提供的日期格式,所以我创建了这个 NSDate 类别 - 希望它对某人有用(这种东西真的应该在标准库中!):)
【讨论】:
还有 SEHumanizedTimeDiff 支持/即将支持多种语言,如果这对您来说是个问题:
【讨论】:
有大约一百万种方法可以做到这一点,但这里有一个快速的方法:
NSString* hoursAgo = [NSString stringWithFormat:@"%.0lf hours ago", fabs([date timeIntervalSinceNow] / 3600.0)]
当然,这并不能检查 date 是否真的来自过去,除了几个小时之外什么都不做。但是,你可能明白了。
timeIntervalSinceNow 返回自给定日期以来经过的秒数,正数表示未来的日期,负数表示过去的日期。所以,我们得到经过了多少秒,将其除以 3600 秒,计算出经过的小时数,然后将其绝对值放入字符串“n hours ago”。
【讨论】:
这是一个很好的答案,从 epoch(1970 年 1 月 1 日)开始需要几秒钟,并返回一个格式不错的字符串,例如“3 分钟前”。只需像这样用您的日期对象调用它:
[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 like 2 分钟前 ------------ 几小时前 2 小时前 ------------天像 2 天前 ------------一周像 2 周前 ------------月份像 2 个月前 最后.... 像 2 年前一样 :) 试试这个
【讨论】:
添加到解决方案试试这个更简化的方法
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];
【讨论】: