为简单起见,我假设您要格式化的日期都是过去的(没有“明天”或“下周”)。并不是说它不能完成,而是需要处理更多的情况并返回更多的字符串。
您可以使用components:fromDate:toDate:options:
使用您想要的任何日期组件组合来获取两个日期之间的年数、月数、周数、天数、小时数等。然后按照从最重要(例如年份)到最不重要(例如日期)的顺序遍历它们,您可以仅根据最重要的组成部分来格式化字符串。
例如:1 周、2 天和 7 小时前的日期将被格式化为“1 week”。
如果您想为单位的特殊编号创建特殊字符串,例如“明天”代表“1 天前”,那么您可以在确定该组件是最重要的组件后检查该组件的值。
代码看起来像这样:
- (NSString *)relativeDateStringForDate:(NSDate *)date
{
NSCalendarUnit units = NSCalendarUnitDay | NSCalendarUnitWeekOfYear |
NSCalendarUnitMonth | NSCalendarUnitYear;
// if `date` is before "now" (i.e. in the past) then the components will be positive
NSDateComponents *components = [[NSCalendar currentCalendar] components:units
fromDate:date
toDate:[NSDate date]
options:0];
if (components.year > 0) {
return [NSString stringWithFormat:@"%ld years ago", (long)components.year];
} else if (components.month > 0) {
return [NSString stringWithFormat:@"%ld months ago", (long)components.month];
} else if (components.weekOfYear > 0) {
return [NSString stringWithFormat:@"%ld weeks ago", (long)components.weekOfYear];
} else if (components.day > 0) {
if (components.day > 1) {
return [NSString stringWithFormat:@"%ld days ago", (long)components.day];
} else {
return @"Yesterday";
}
} else {
return @"Today";
}
}
如果您的日期也可能是将来的日期,那么您可以按相同顺序检查组件的绝对值,然后检查它是正数还是负数以返回适当的字符串。我只显示下面的年份:
if ( abs(components.year > 0) ) {
// year is most significant component
if (components.year > 0) {
// in the past
return [NSString stringWithFormat:@"%ld years ago", (long)components.year];
} else {
// in the future
return [NSString stringWithFormat:@"In %ld years", (long)components.year];
}
}