使用自定义样式进行RelativeDateFormatting - 可能吗?

问题描述 投票:0回答:2

我想将

doesRelativeDateFormatting
与 Swift 一起使用,以便在我的应用程序上显示日期时获得更多人类可读的日期,例如“今天”或“明天”。但是,当显示非相对日期时,我想显示自定义样式,例如“Wed, Feb 10 '18”。

到目前为止,我可以将预定义的

dateStyle
之一与 DateFormatter 对象一起使用,例如
.short
.medium
,但这些都不会显示工作日和月份的缩写。当使用字符串中的自定义格式(例如“EEE,MMM d yy”)时,我会丢失相对日期。

这是一种使用两者并显示相对日期(当它们存在时)以及所有其他日期的自定义日期的方法吗?

swift date nsdateformatter
2个回答
13
投票

当不使用相对格式时,没有直接的方法来获取相对格式和自定义格式。您最多可以指定样式,但不能指定格式。

一种解决方案是使用使用三个日期格式化程序的辅助方法。一种使用具有所需样式的相对格式,一种不是相对但使用相同的样式,一种使用非相对日期的自定义格式。

func formatDate(_ date: Date) -> String {
    // Setup the relative formatter
    let relDF = DateFormatter()
    relDF.doesRelativeDateFormatting = true
    relDF.dateStyle = .long
    relDF.timeStyle = .medium

    // Setup the non-relative formatter
    let absDF = DateFormatter()
    absDF.dateStyle = .long
    absDF.timeStyle = .medium

    // Get the result of both formatters
    let rel = relDF.string(from: date)
    let abs = absDF.string(from: date)

    // If the results are the same then it isn't a relative date.
    // Use your custom formatter. If different, return the relative result.
    if (rel == abs) {
        let fullDF = DateFormatter()
        fullDF.setLocalizedDateFormatFromTemplate("EEE, MMM d yy")
        return fullDF.string(from: date)
    } else {
        return rel
    }
}

print(formatDate(Date()))
print(formatDate(Calendar.current.date(byAdding: .day, value: 1, to: Date())!))
print(formatDate(Calendar.current.date(byAdding: .day, value: 7, to: Date())!))

输出:

今天上午 11:01:16
明天上午 11:01:16
18 年 2 月 20 日星期二

如果您需要格式化大量日期,您将需要修改此代码,以便它创建所有格式化程序一次,然后在此方法中重用它们。


0
投票
@interface IPEDateFormatter ()
@property (nonatomic, strong) NSDateFormatter *relative;
@end

@implementation IPEDateFormatter

- (id)init{
    if (self = [super init]){
        _relative = [NSDateFormatter new];
        _relative.doesRelativeDateFormatting = YES;
        _relative.timeStyle = NSDateFormatterNoStyle;
        _relative.dateStyle = NSDateFormatterFullStyle;
    }
    return self;
}

- (NSString*)stringFromDate:(NSDate *)date{
    NSString *string;
    if (self.doesRelativeDateFormatting){
        NSDateComponents *components =
        [self.calendar components:NSCalendarUnitDay
                         fromDate:[NSDate date]
                           toDate:date
                          options:(NSCalendarOptions)0];
        // components.day
        // -2 = day before yesterday,
        // -1 = yesterday,
        // 0 = today,
        // +1 = tomorrow
        // +2 = day after tomorrow
        switch(components.day){
            case 0:
            case -1: string = [_relative stringFromDate:date]; break;
            default: string = [super stringFromDate:date]; break;
        }
    }
    else{
        string = [super stringFromDate:date];
    }
    return string;
}

- (NSDate*)dateFromString:(NSString *)string{
    NSDate *date = [super dateFromString:string];
    if (!date){
        if (self.doesRelativeDateFormatting){
            date = [_relative dateFromString:string];
        }
    }
    return date;
}

@end
© www.soinside.com 2019 - 2024. All rights reserved.