12

所以我的意图是列出如下所示的日期:

Today, August 28
Tomorrow, August 29
Friday, August 30
...etc

问题是我似乎只能靠得这么近。

当 IsetDoesRelativeDateFormatting:YESsetDateStyletoFullsetTimeStyleto 时None,它会产生如下结果:

Today
Tomorrow
Friday, August 30, 2013

这会产生年份,但不会产生今天和明天的月份和日期。

我试过的另一个代码是这样的:

[NSDateFormatter dateFormatFromTemplate:@"eeeedMMM" options:0
                                                     locale:[NSLocale currentLocale]];

这会产生以下结果:

Wednesday, August 28
Thursday, August 29
Friday, August 30

看起来,dateStyle 和 timeStyle,或相对日期格式会覆盖自定义格式。

有没有办法在不进入自定义实现的情况下完成这种日期格式?

提前致谢!

4

3 回答 3

3

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

如果日期格式化程序使用相对日期格式化,它会在可能的情况下用表示相对日期的短语(例如“今天”或“明天”)替换其输出的日期部分。可用的短语取决于日期格式化程序的语言环境;而对于未来的日期,英语可能只允许“明天”,法语可能允许“后天后天”。

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

于 2014-02-03T13:27:22.223 回答
3

如果不进入自定义实现,似乎没有办法完成这种日期格式。所以,这个问题的简短回答是“不”。

但是,问题仍然存在,所以下面是我自己解决问题的方法。

创建 NSDateFormatter 的子类并实现自定义的 init 和 overridestringFromDate:方法。

- (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;
}

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

如果字符串中有数字,我们假设没有发生相对格式,所以我们应用我们自己的日期格式。

于 2015-02-23T03:44:49.407 回答
3

我在 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
    }
}
于 2016-10-23T11:20:45.513 回答