NSDateFormatter setDateFormat的序数月 - 日后缀选项

Mat*_*sen 60 iphone cocoa nsdate nsdateformatter

我使用什么setDateFormat选项获取NSDateFormatter来获取一个月的序数后缀?

例如,下面的片段目前产生:
8月15日星期六下午3:11

我必须改变什么:
8月15 星期六下午3:11

NSDate *date = [NSDate date];
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
[dateFormatter setDateFormat:@"h:mm a EEEE MMMM d"];
NSString *dateString = [dateFormatter stringFromDate:date]; 
NSLog(@"%@", dateString);
Run Code Online (Sandbox Code Playgroud)

在PHP中,我将在上面的例子中使用它:
<?php echo date('h:m A l F jS') ?>

是否有一个NSDateFormatter等效于PHP格式化字符串中的S选项?

cbh*_*000 94

这些答案中没有一个像我正在使用的那样美观,所以我想我会分享:


斯威夫特3:

func daySuffix(from date: Date) -> String {
    let calendar = Calendar.current
    let dayOfMonth = calendar.component(.day, from: date)
    switch dayOfMonth {
    case 1, 21, 31: return "st"
    case 2, 22: return "nd"
    case 3, 23: return "rd"
    default: return "th"
    }
}
Run Code Online (Sandbox Code Playgroud)

Objective-C的:

- (NSString *)daySuffixForDate:(NSDate *)date {
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSInteger dayOfMonth = [calendar component:NSCalendarUnitDay fromDate:date];
    switch (dayOfMonth) {
        case 1:
        case 21:
        case 31: return @"st";
        case 2:
        case 22: return @"nd";
        case 3:
        case 23: return @"rd";
        default: return @"th";
    }
}
Run Code Online (Sandbox Code Playgroud)

显然,这只适用于英语.

  • 这个答案根本不处理本地化。请改用序数格式化程序来格式化数字,如下所示! (4认同)
  • 这是最好的答案! (2认同)
  • @BenSullivan如果你打算这样做,如果应该是`'F'\(daySuffix(date))'MM yy"`.注意ticks,它告诉NSDateFormatter"th","st"和"rd"不应该被解释为特殊符号. (2认同)

Mat*_*sen 54

NSDate *date = [NSDate date];
NSDateFormatter *prefixDateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[prefixDateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
[prefixDateFormatter setDateFormat:@"h:mm a EEEE MMMM d"];
NSString *prefixDateString = [prefixDateFormatter stringFromDate:date];
NSDateFormatter *monthDayFormatter = [[[NSDateFormatter alloc] init] autorelease];
[monthDayFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
[monthDayFormatter setDateFormat:@"d"];     
int date_day = [[monthDayFormatter stringFromDate:date] intValue];  
NSString *suffix_string = @"|st|nd|rd|th|th|th|th|th|th|th|th|th|th|th|th|th|th|th|th|th|st|nd|rd|th|th|th|th|th|th|th|st";
NSArray *suffixes = [suffix_string componentsSeparatedByString: @"|"];
NSString *suffix = [suffixes objectAtIndex:date_day];   
NSString *dateString = [prefixDateString stringByAppendingString:suffix];   
NSLog(@"%@", dateString);
Run Code Online (Sandbox Code Playgroud)

  • 我对这个答案进行了投票,因为为每一天创建一个字符串,拆分字符串,然后使用该日作为索引是脆弱和混淆的.阅读:很容易出错,它可能会崩溃,而且很难遵循.我确信马特现在是一个更好的程序员,但我不同意这里的40多名赞助人. (8认同)
  • 这是一个有效的答案,因为它完全忽略了用户的语言环境?NSDateFormatter根本不支持该功能. (6认同)
  • iOS 9支持NSNumberFormatter:http://stackoverflow.com/a/31033712/276626 (6认同)
  • 我可能做的唯一改进就是简单地创建数组,而不是从componentsSeparatedByString生成它.这可以使用Array文字语法@ [@"st",@"nd",@"rd",...]轻松完成. (2认同)

Ger*_*Ger 26

这很容易在iOS9中完成

NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.numberStyle = NSNumberFormatterOrdinalStyle;
NSArray<NSNumber *> *numbers = @[@1, @2, @3, @4, @5];

for (NSNumber *number in numbers) {
    NSLog(@"%@", [formatter stringFromNumber:number]);
}
// "1st", "2nd", "3rd", "4th", "5th"
Run Code Online (Sandbox Code Playgroud)

取自NSHipster

Swift 2.2:

let numberFormatter = NSNumberFormatter()
numberFormatter.numberStyle = .OrdinalStyle
let numbers: [Int] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for number in numbers {
    print(numberFormatter.stringFromNumber(number)!)
}
Run Code Online (Sandbox Code Playgroud)

  • 这很好,但我们仍然可以使用适用于NSDateFormatter的东西. (2认同)

SDJ*_*tie 16

这是生成后缀的方法的另一个实现.它产生的后缀仅在英语中有效,在其他语言中可能不正确:

- (NSString *)suffixForDayInDate:(NSDate *)date
{
    NSInteger day = [[[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] components:NSDayCalendarUnit fromDate:date] day];
    if (day >= 11 && day <= 13) {
        return @"th";
    } else if (day % 10 == 1) {
        return @"st";
    } else if (day % 10 == 2) {
        return @"nd";
    } else if (day % 10 == 3) {
        return @"rd";
    } else {
        return @"th";
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这失败了一天价值11 (2认同)
  • 你是对的 - 不敢相信我没注意到.固定! (2认同)

Tim*_*Tim 9

Mac OS 10.5和iPhone上的日期格式化程序使用TR35作为其格式说明符标准.此规范不允许在任何日期使用此类后缀; 如果你想要一个,你必须自己生成它.


Ste*_*sen 6

这将分两步进行格式化:首先,创建一个带有适当后缀的日期的子字符串,然后为其余部分创建一个格式字符串,插入已经格式化的日期。

func ordinalDate(date: Date) -> String {
    let ordinalFormatter = NumberFormatter()
    ordinalFormatter.numberStyle = .ordinal
    let day = Calendar.current.component(.day, from: date)
    let dayOrdinal = ordinalFormatter.string(from: NSNumber(value: day))!

    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "h:mm a EEEE MMMM '\(dayOrdinal)'"
    return dateFormatter.string(from: Date())
}
Run Code Online (Sandbox Code Playgroud)

由于序数日由 构建NumberFormatter,因此它应该适用于所有语言,而不仅仅是英语。

您可以通过将分配替换为以下内容来获取为当前语言环境排序的格式字符串dateFormat

dateFormatter.dateFormat = DateFormatter.dateFormat(fromTemplate: "h:mm a EEEE MMMM d", options: 0, locale: dateFormatter.locale)?.replacingOccurrences(of: "d", with: "'\(dayOrdinal)'")
Run Code Online (Sandbox Code Playgroud)

请注意其他几个人的建议,即创建格式化程序的成本很高,因此您应该在经常调用的代码中缓存和重用它们。

  • 因为这就是文档所说的:[日期格式指南](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/DataFormatting/Articles/dfDateFormatting10_4.html)。固定格式使用 [Unicode 技术标准 #35](http://www.unicode.org/reports/tr35/tr35-31/tr35-dates.html#Date_Format_Patterns) 定义的语法。 (2认同)

小智 6

这已在基金会中实现。

let numberFormatter = NumberFormatter()
numberFormatter.numberStyle = .ordinal
numberFormatter.locale = Locale.current

numberFormatter.string(for: 1) //Should produce 1st
numberFormatter.string(for: 2) //Should produce 2nd
numberFormatter.string(for: 3) //Should produce 3rd
numberFormatter.string(for: 4) //Should produce 4th
Run Code Online (Sandbox Code Playgroud)