Objective c NSDateFormatter自定义格式的相对日期格式

Objective c NSDateFormatter自定义格式的相对日期格式,objective-c,nsdateformatter,relative-date,Objective C,Nsdateformatter,Relative Date,因此,我打算列出如下日期: Today, August 28 Tomorrow, August 29 Friday, August 30 ...etc Wednesday, August 28 Thursday, August 29 Friday, August 30 问题是我似乎只能靠这么近 当IsetDoesRelativeDateFormatting:YES和setDateStyle到Full和setTimeStyle到None时,会产生如下结果: Today Tomorrow Fri

因此,我打算列出如下日期:

Today, August 28
Tomorrow, August 29
Friday, August 30
...etc
Wednesday, August 28
Thursday, August 29
Friday, August 30
问题是我似乎只能靠这么近

当I
setDoesRelativeDateFormatting:YES
setDateStyle
Full
setTimeStyle
None
时,会产生如下结果:

Today
Tomorrow
Friday, August 30, 2013
这会产生年份,而不会产生今天和明天的月份和日期

我尝试过的另一个代码是:

[NSDateFormatter dateFormatFromTemplate:@"eeeedMMM" options:0
                                                     locale:[NSLocale currentLocale]];
这将产生以下结果:

Today, August 28
Tomorrow, August 29
Friday, August 30
...etc
Wednesday, August 28
Thursday, August 29
Friday, August 30
看起来,日期样式和时间样式或相对日期格式覆盖了自定义格式

有没有一种方法可以在不进入自定义实现的情况下实现此日期格式


提前谢谢

根据有关NSDateFormatter的文档,我认为解决您的问题的唯一方法是为您希望相对显示的日期提供两个日期字符串。你应该记住,在不同的语言中,相对日期是不同的。从文件中:

如果日期格式化程序使用相对日期格式,则在可能的情况下,它会将其输出的日期组件替换为表示相对日期的短语,如“今天”或“明天”。可用短语取决于日期格式化程序的区域设置;然而,对于未来的日期,英语可能只允许“明天”,法语可能允许“后天”


我相信,如果您定义要相对显示,例如昨天、今天和明天,您可以使用2个NSDateFormatter。使用第一个NSDateFormatter,您将显示相对值,使用第二个NSDateFormatter,您将显示实际日期。对于非相对日期,您将只显示非相对值。

似乎没有实现这种日期格式的方法,而无需进入自定义实现。因此,这个问题的简短答案是“否”

然而,这个问题仍然存在,下面是我自己解决这个问题的方法

创建NSDateFormatter的子类,实现自定义init并重写
stringFromDate:
方法

- (instancetype)initWithDateFormat:(NSString *)dateFormat
{
    self = [super init];
    if (self) {
        NSLocale *locale = [NSLocale currentLocale];
        self.locale = locale;

        self.timeStyle = NSDateFormatterNoStyle;
        self.dateStyle = NSDateFormatterShortStyle;
        self.doesRelativeDateFormatting = YES;

        self.dateFormat = dateFormat;
    }
    return self;
}

- (NSString *)stringFromDate:(NSDate *)date
{
    NSString *dateFormat = self.dateFormat;
    self.dateFormat = nil;

    BOOL didRelativeDateFormatting = self.doesRelativeDateFormatting;
    self.doesRelativeDateFormatting = YES;

    NSString *result = [super stringFromDate:date];

    if ([result rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet]].location != NSNotFound) {
        self.dateFormat = dateFormat;
        self.doesRelativeDateFormatting = NO;
        result = [super stringFromDate:date];
    }

    self.dateFormat = dateFormat;
    self.doesRelativeDateFormatting = didRelativeDateFormatting;

    return result;
}
由于
doesRelativeDateFormatting
dateFormat
是互斥的,我们尝试首先使用相对格式。鉴于我们在init方法中设置了
self.dateStyle=NSDateFormatterShortStyle
,我们知道日期将包含十进制数字,除非它被替换为表示“今天”、“明天”和任何其他含义的单词如果我们没有发现任何数字,我们就接受这个结果


如果字符串中有数字,我们假设没有出现相对格式,因此我们采用自己的日期格式。

我在Swift 3中使用这种方法:

struct SharedFormatters {
    private static let dateWithRelativeFormatting: DateFormatter = {
        let df = DateFormatter()
        df.dateStyle = .medium
        df.doesRelativeDateFormatting = true
        return df
    }()
    private static let dateWithoutRelativeFormatting: DateFormatter = {
        let df = DateFormatter()
        df.dateStyle = .medium
        df.doesRelativeDateFormatting = false
        return df
    }()
    private static let longDateWithoutYear: DateFormatter = {
        let df = DateFormatter()
        df.dateFormat = "MMMM d"
        df.doesRelativeDateFormatting = false
        return df
    }()
    static func string(from date: Date) -> String {
        let val = dateWithRelativeFormatting.string(from: date)
        let val2 = dateWithoutRelativeFormatting.string(from: date)
        return val == val2 ? longDateWithoutYear.string(from: date) : val
    }
}

rmaddy没有问这个问题。诀窍是找出相对格式实际发生的时间。你不能只依赖于前一天和后一天。在其他语言中,例如法语和俄语,你会有“昨天之前”和“明天之后”的相对格式。这实际上是个聪明的主意。如果你有e需要格式化很多日期(例如在表格中),因为这会使正在进行的格式化数量增加三倍。