Gil*_*ean 39 iphone time cocoa datetime objective-c
我有一个时间戳作为字符串,如:
星期四,2009年5月21日19:10:09 -0700
而且我想将它转换为像'20分钟前'或'3天前'的相对时间戳.
使用Objective-C为iPhone做到这一点的最佳方法是什么?
Gil*_*ean 72
-(NSString *)dateDiff:(NSString *)origDate {
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setFormatterBehavior:NSDateFormatterBehavior10_4];
[df setDateFormat:@"EEE, dd MMM yy HH:mm:ss VVVV"];
NSDate *convertedDate = [df dateFromString:origDate];
[df release];
NSDate *todayDate = [NSDate date];
double ti = [convertedDate timeIntervalSinceDate:todayDate];
ti = ti * -1;
if(ti < 1) {
return @"never";
} else if (ti < 60) {
return @"less than a minute ago";
} else if (ti < 3600) {
int diff = round(ti / 60);
return [NSString stringWithFormat:@"%d minutes ago", diff];
} else if (ti < 86400) {
int diff = round(ti / 60 / 60);
return[NSString stringWithFormat:@"%d hours ago", diff];
} else if (ti < 2629743) {
int diff = round(ti / 60 / 60 / 24);
return[NSString stringWithFormat:@"%d days ago", diff];
} else {
return @"never";
}
}
Run Code Online (Sandbox Code Playgroud)
ste*_*anB 22
以下是来自Cocoa的方法,可以帮助您获取相关信息(不确定它们是否都可以通过coca-touch获得).
NSDate * today = [NSDate date];
NSLog(@"today: %@", today);
NSString * str = @"Thu, 21 May 09 19:10:09 -0700";
NSDate * past = [NSDate dateWithNaturalLanguageString:str
locale:[[NSUserDefaults
standardUserDefaults] dictionaryRepresentation]];
NSLog(@"str: %@", str);
NSLog(@"past: %@", past);
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
unsigned int unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit |
NSDayCalendarUnit |
NSHourCalendarUnit | NSMinuteCalendarUnit |
NSSecondCalendarUnit;
NSDateComponents *components = [gregorian components:unitFlags
fromDate:past
toDate:today
options:0];
NSLog(@"months: %d", [components month]);
NSLog(@"days: %d", [components day]);
NSLog(@"hours: %d", [components hour]);
NSLog(@"seconds: %d", [components second]);
Run Code Online (Sandbox Code Playgroud)
NSDateComponents对象似乎在相关单位中保持差异(如指定的那样).如果指定所有单位,则可以使用此方法:
void dump(NSDateComponents * t)
{
if ([t year]) NSLog(@"%d years ago", [t year]);
else if ([t month]) NSLog(@"%d months ago", [t month]);
else if ([t day]) NSLog(@"%d days ago", [t day]);
else if ([t minute]) NSLog(@"%d minutes ago", [t minute]);
else if ([t second]) NSLog(@"%d seconds ago", [t second]);
}
Run Code Online (Sandbox Code Playgroud)
如果你想自己计算,你可以看看:
NSDate timeIntervalSinceDate
Run Code Online (Sandbox Code Playgroud)
然后在算法中使用秒.
免责声明:如果这个界面被弃用(我还没有检查过),苹果公司首选的做法NSDateFormatters
,如下面的评论所示,看起来也很漂亮 - 我会保留我的答案,因为历史原因,它可能仍然是有些人可以看一下使用的逻辑.
Car*_*tin 14
我还无法编辑,但我采用了Gilean的代码并进行了一些调整,并使其成为NSDateFormatter的一个类别.
它接受一个格式字符串,因此它将使用任意字符串,并且我添加了if子句以使单个事件在语法上正确.
干杯,
卡尔CM
@interface NSDateFormatter (Extras)
+ (NSString *)dateDifferenceStringFromString:(NSString *)dateString
withFormat:(NSString *)dateFormat;
@end
@implementation NSDateFormatter (Extras)
+ (NSString *)dateDifferenceStringFromString:(NSString *)dateString
withFormat:(NSString *)dateFormat
{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
[dateFormatter setDateFormat:dateFormat];
NSDate *date = [dateFormatter dateFromString:dateString];
[dateFormatter release];
NSDate *now = [NSDate date];
double time = [date timeIntervalSinceDate:now];
time *= -1;
if(time < 1) {
return dateString;
} else if (time < 60) {
return @"less than a minute ago";
} else if (time < 3600) {
int diff = round(time / 60);
if (diff == 1)
return [NSString stringWithFormat:@"1 minute ago", diff];
return [NSString stringWithFormat:@"%d minutes ago", diff];
} else if (time < 86400) {
int diff = round(time / 60 / 60);
if (diff == 1)
return [NSString stringWithFormat:@"1 hour ago", diff];
return [NSString stringWithFormat:@"%d hours ago", diff];
} else if (time < 604800) {
int diff = round(time / 60 / 60 / 24);
if (diff == 1)
return [NSString stringWithFormat:@"yesterday", diff];
if (diff == 7)
return [NSString stringWithFormat:@"last week", diff];
return[NSString stringWithFormat:@"%d days ago", diff];
} else {
int diff = round(time / 60 / 60 / 24 / 7);
if (diff == 1)
return [NSString stringWithFormat:@"last week", diff];
return [NSString stringWithFormat:@"%d weeks ago", diff];
}
}
@end
Run Code Online (Sandbox Code Playgroud)
为了完整性,基于@Gilean的答案,这里是NSDate上一个简单类别的完整代码,模仿rails的漂亮日期帮助器.有关类别的更新,这些是您将在NSDate对象上调用的实例方法.所以,如果我有一个代表昨天的NSDate,[myDate distanceOfTimeInWordsToNow] =>"1天".
希望它有用!
@interface NSDate (NSDate_Relativity)
-(NSString *)distanceOfTimeInWordsSinceDate:(NSDate *)aDate;
-(NSString *)distanceOfTimeInWordsToNow;
@end
@implementation NSDate (NSDate_Relativity)
-(NSString *)distanceOfTimeInWordsToNow {
return [self distanceOfTimeInWordsSinceDate:[NSDate date]];
}
-(NSString *)distanceOfTimeInWordsSinceDate:(NSDate *)aDate {
double interval = [self timeIntervalSinceDate:aDate];
NSString *timeUnit;
int timeValue;
if (interval < 0) {
interval = interval * -1;
}
if (interval< 60) {
return @"seconds";
} else if (interval< 3600) { // minutes
timeValue = round(interval / 60);
if (timeValue == 1) {
timeUnit = @"minute";
} else {
timeUnit = @"minutes";
}
} else if (interval< 86400) {
timeValue = round(interval / 60 / 60);
if (timeValue == 1) {
timeUnit = @"hour";
} else {
timeUnit = @"hours";
}
} else if (interval< 2629743) {
int days = round(interval / 60 / 60 / 24);
if (days < 7) {
timeValue = days;
if (timeValue == 1) {
timeUnit = @"day";
} else {
timeUnit = @"days";
}
} else if (days < 30) {
int weeks = days / 7;
timeValue = weeks;
if (timeValue == 1) {
timeUnit = @"week";
} else {
timeUnit = @"weeks";
}
} else if (days < 365) {
int months = days / 30;
timeValue = months;
if (timeValue == 1) {
timeUnit = @"month";
} else {
timeUnit = @"months";
}
} else if (days < 30000) { // this is roughly 82 years. After that, we'll say 'forever'
int years = days / 365;
timeValue = years;
if (timeValue == 1) {
timeUnit = @"year";
} else {
timeUnit = @"years";
}
} else {
return @"forever ago";
}
}
return [NSString stringWithFormat:@"%d %@", timeValue, timeUnit];
}
@end
Run Code Online (Sandbox Code Playgroud)
已经有很多答案出现在同一个解决方案中,但选择却不会有什么坏处.这就是我想出来的.
- (NSString *)stringForTimeIntervalSinceCreated:(NSDate *)dateTime
{
NSDictionary *timeScale = @{@"second":@1,
@"minute":@60,
@"hour":@3600,
@"day":@86400,
@"week":@605800,
@"month":@2629743,
@"year":@31556926};
NSString *scale;
int timeAgo = 0-(int)[dateTime timeIntervalSinceNow];
if (timeAgo < 60) {
scale = @"second";
} else if (timeAgo < 3600) {
scale = @"minute";
} else if (timeAgo < 86400) {
scale = @"hour";
} else if (timeAgo < 605800) {
scale = @"day";
} else if (timeAgo < 2629743) {
scale = @"week";
} else if (timeAgo < 31556926) {
scale = @"month";
} else {
scale = @"year";
}
timeAgo = timeAgo/[[timeScale objectForKey:scale] integerValue];
NSString *s = @"";
if (timeAgo > 1) {
s = @"s";
}
return [NSString stringWithFormat:@"%d %@%@ ago", timeAgo, scale, s];
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
43016 次 |
最近记录: |