NSDateFormatter非常支持生成相关日期,例如“今天”,“明天”,“昨天”,当前语言支持这些日期。一个很大的优点是所有这些都已经为您本地化了 - 您不需要翻译字符串。
您可以使用以下方式启用此功能:
[dateFormatter setDoesRelativeDateFormatting: YES];
缺点是,这似乎只适用于使用其中一种预定义格式的实例,例如:
[dateFormatter setDateStyle: NSDateFormatterShortStyle];
如果您设置日期格式化程序以使用自定义格式,请执行以下操作:
[dateFormatter setDateStyle: @"EEEE"];
然后当你打电话:
[dateFormatter stringFromDate: date];
...你只会得到一个空字符串。
我希望能够在可能的情况下获得相关字符串,并在不存在时使用我自己的自定义格式。
答案 0 :(得分:9)
我在NSDateFormatter上设置了一个类别,为此提供了一种解决方法。代码后面有一个解释。
在NSDateFormatter + RelativeDateFormat.h中:
@interface NSDateFormatter (RelativeDateFormat)
-(NSString*) relativeStringFromDateIfPossible:(NSDate *)date;
@end
在NSDateFormatter + RelativeDateFormat.m中:
@implementation NSDateFormatter (RelativeDateFormat)
-(NSString*) relativeStringFromDateIfPossible:(NSDate *)date
{
static NSDateFormatter *relativeFormatter;
static NSDateFormatter *absoluteFormatter;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
const NSDateFormatterStyle arbitraryStyle = NSDateFormatterShortStyle;
relativeFormatter = [[NSDateFormatter alloc] init];
[relativeFormatter setDateStyle: arbitraryStyle];
[relativeFormatter setTimeStyle: NSDateFormatterNoStyle];
[relativeFormatter setDoesRelativeDateFormatting: YES];
absoluteFormatter = [[NSDateFormatter alloc] init];
[absoluteFormatter setDateStyle: arbitraryStyle];
[absoluteFormatter setTimeStyle: NSDateFormatterNoStyle];
[absoluteFormatter setDoesRelativeDateFormatting: NO];
});
NSLocale *const locale = [self locale];
if([relativeFormatter locale] != locale)
{
[relativeFormatter setLocale: locale];
[absoluteFormatter setLocale: locale];
}
NSCalendar *const calendar = [self calendar];
if([relativeFormatter calendar] != calendar)
{
[relativeFormatter setCalendar: calendar];
[absoluteFormatter setCalendar: calendar];
}
NSString *const maybeRelativeDateString = [relativeFormatter stringFromDate: date];
const BOOL isRelativeDateString = ![maybeRelativeDateString isEqualToString: [absoluteFormatter stringFromDate: date]];
if(isRelativeDateString)
{
return maybeRelativeDateString;
}
else
{
return [self stringFromDate: date];
}
}
@end
它使用(任意)标准格式维护两个日期格式化程序。它们的格式相同,除了一个将提供相对日期字符串而另一个不提供。
通过使用两种格式化程序格式化给定日期,可以查看相对日期格式化程序是否给出特殊的相对日期。当两个格式化程序提供不同的结果时,会有一个特殊的相对日期。
您可以找到有关dispatch_once
here的更多信息。
该实现不处理您可能放入格式字符串的时间组件。当相对日期字符串可用时,将忽略您的格式标记,并获得相对日期字符串。
答案 1 :(得分:1)
我认为@Benjohn代码的快速版本对其他人有用
extension NSDateFormatter {
@nonobjc static let relativeFormatter : NSDateFormatter = {
let formatter = NSDateFormatter()
formatter.dateStyle = .MediumStyle
formatter.timeStyle = .NoStyle
formatter.doesRelativeDateFormatting = true
return formatter
}()
@nonobjc static let absoluteFormatter : NSDateFormatter = {
let formatter = NSDateFormatter()
formatter.dateStyle = .MediumStyle
formatter.timeStyle = .NoStyle
formatter.doesRelativeDateFormatting = false
return formatter
}()
func relativeStringFromDateIfPossible(date:NSDate) -> String
{
if NSDateFormatter.relativeFormatter.locale != locale {
NSDateFormatter.relativeFormatter.locale = locale
NSDateFormatter.absoluteFormatter.locale = locale
}
if NSDateFormatter.absoluteFormatter.calendar != calendar {
NSDateFormatter.relativeFormatter.calendar = calendar
NSDateFormatter.absoluteFormatter.calendar = calendar
}
let maybeRelativeString = NSDateFormatter.relativeFormatter.stringFromDate(date)
let absoluteString = NSDateFormatter.absoluteFormatter.stringFromDate(date)
return (maybeRelativeString != absoluteString ) ? maybeRelativeString : stringFromDate(date)
}
}