NSNumberFormatter和'th''st''nd''rd'(有序)数字结尾

有没有办法使用NSNumberFormatter来获取“th”“st”“nd”“rd”数字结尾?

编辑:

看起来不存在 这是我正在使用的。

+(NSString*)ordinalNumberFormat:(NSInteger)num{ NSString *ending; int ones = num % 10; int tens = floor(num / 10); tens = tens % 10; if(tens == 1){ ending = @"th"; }else { switch (ones) { case 1: ending = @"st"; break; case 2: ending = @"nd"; break; case 3: ending = @"rd"; break; default: ending = @"th"; break; } } return [NSString stringWithFormat:@"%d%@", num, ending]; } 

从nickf的答案适应在这里有一个简单的方法在.NET中获得“st”,“nd”,“rd”和“th”结尾的数字?

由于这个问题需要一个数字格式化程序,所以我做了一个粗略的。

 // // OrdinalNumberFormatter.h // #import <Foundation/Foundation.h> @interface OrdinalNumberFormatter : NSNumberFormatter { } @end 

并执行:

 // // OrdinalNumberFormatter.m // #import "OrdinalNumberFormatter.h" @implementation OrdinalNumberFormatter - (BOOL)getObjectValue:(id *)anObject forString:(NSString *)string errorDescription:(NSString **)error { NSInteger integerNumber; NSScanner *scanner; BOOL isSuccessful = NO; NSCharacterSet *letters = [NSCharacterSet letterCharacterSet]; scanner = [NSScanner scannerWithString:string]; [scanner setCaseSensitive:NO]; [scanner setCharactersToBeSkipped:letters]; if ([scanner scanInteger:&integerNumber]){ isSuccessful = YES; if (anObject) { *anObject = [NSNumber numberWithInteger:integerNumber]; } } else { if (error) { *error = [NSString stringWithFormat:@"Unable to create number from %@", string]; } } return isSuccessful; } - (NSString *)stringForObjectValue:(id)anObject { if (![anObject isKindOfClass:[NSNumber class]]) { return nil; } NSString *strRep = [anObject stringValue]; NSString *lastDigit = [strRep substringFromIndex:([strRep length]-1)]; NSString *ordinal; if ([strRep isEqualToString:@"11"] || [strRep isEqualToString:@"12"] || [strRep isEqualToString:@"13"]) { ordinal = @"th"; } else if ([lastDigit isEqualToString:@"1"]) { ordinal = @"st"; } else if ([lastDigit isEqualToString:@"2"]) { ordinal = @"nd"; } else if ([lastDigit isEqualToString:@"3"]) { ordinal = @"rd"; } else { ordinal = @"th"; } return [NSString stringWithFormat:@"%@%@", strRep, ordinal]; } @end 

将其实例化为Interface Builder对象,并将Text Field的格式化程序插件附加到它。 为了更好的控制(比如设置最大值和最小值,你应该创build一个格式化程序的实例,根据需要设置属性,并使用它的setFormatter:方法将其附加到文本字段。

你可以从GitHub下载这个类 (包括一个示例项目)

从iOS 9开始,正确的做法是:

 NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init]; numberFormatter.numberStyle = NSNumberFormatterOrdinalStyle; NSLog(@"%@", [numberFormatter stringFromNumber:@(1)]); // 1st NSLog(@"%@", [numberFormatter stringFromNumber:@(2)]); // 2nd NSLog(@"%@", [numberFormatter stringFromNumber:@(3)]); // 3rd, etc. 

这在一种方法(对于英语)中有效。 感谢nickf https://stackoverflow.com/a/69284/1208690原始代码在PHP中,我只是适应它&#x7684;objective C : –

 -(NSString *) addSuffixToNumber:(int) number { NSString *suffix; int ones = number % 10; int tens = (number/10) % 10; if (tens ==1) { suffix = @"th"; } else if (ones ==1){ suffix = @"st"; } else if (ones ==2){ suffix = @"nd"; } else if (ones ==3){ suffix = @"rd"; } else { suffix = @"th"; } NSString * completeAsString = [NSString stringWithFormat:@"%d%@", number, suffix]; return completeAsString; } 

其他Swift解决scheme不会产生正确的结果并包含错误。 我已经将CmKndy解决scheme转换为Swift

 extension Int { var ordinal: String { var suffix: String let ones: Int = self % 10 let tens: Int = (self/10) % 10 if tens == 1 { suffix = "th" } else if ones == 1 { suffix = "st" } else if ones == 2 { suffix = "nd" } else if ones == 3 { suffix = "rd" } else { suffix = "th" } return "\(self)\(suffix)" } } 

testing结果:0日1日2日3日4日5日6日7日8日9日10日11日12日13日14日15日16日17日18日19日20日21日22日23日

截至iOS 9

Swift 3

 let value = 1 let formatter = NSNumberFormatter() formatter.numberStyle = .ordinalStyle formatter.string(from: NSNumber(short: value)) 

只需添加另一个实现作为类方法。 我没有看到这个问题,直到我实现了这个从一个例子在PHP。

 + (NSString *)buildRankString:(NSNumber *)rank { NSString *suffix = nil; int rankInt = [rank intValue]; int ones = rankInt % 10; int tens = floor(rankInt / 10); tens = tens % 10; if (tens == 1) { suffix = @"th"; } else { switch (ones) { case 1 : suffix = @"st"; break; case 2 : suffix = @"nd"; break; case 3 : suffix = @"rd"; break; default : suffix = @"th"; } } NSString *rankString = [NSString stringWithFormat:@"%@%@", rank, suffix]; return rankString; } 

英文很简单 这是一个迅速的扩展:

 extension Int { var ordinal: String { get { var suffix = "th" switch self % 10 { case 1: suffix = "st" case 2: suffix = "nd" case 3: suffix = "rd" default: () } if 10 < (self % 100) && (self % 100) < 20 { suffix = "th" } return String(self) + suffix } } } 

然后调用类似于:

  cell.label_position.text = (path.row + 1).ordinal 

这是一个适合所有整数types的紧凑的Swift扩展:

 extension IntegerType { func ordinalString() -> String { switch self % 10 { case 1...3 where 11...13 ~= self % 100: return "\(self)" + "th" case 1: return "\(self)" + "st" case 2: return "\(self)" + "nd" case 3: return "\(self)" + "rd" default: return "\(self)" + "th" } } } 

用法示例:

 let numbers = (0...30).map { $0.ordinalString() } print(numbers.joinWithSeparator(", ")) 

输出:

第一,二,三,四,五,六,七,八,九,十,十一,十二,十三,十四,十五,十六,十八,十九,二十,二十一,二十二,二十三,二十四, 25日,26日,27日,28日,29日,30日

我不知道这个能力。 不过,你可以自己做这个。 在英语中,序数(th,st,nd,rd等)有一个非常简单的模式:

如果数字以:=>结束使用:

  • 0 => th
  • 1 => st
  • 2 => nd
  • 3 => rd
  • 4 => th
  • 5 => th
  • 6 => th
  • 7 => th
  • 8 => th
  • 9 => th
  • 11 => th
  • 12 => th
  • 13 => th

这不会为你拼写出这个单词,但它可以让你做一些事情:“第42”,“第1340697”等

如果你需要本地化,这会变得更加复杂。

这将date转换为string,并在date中添加序号。 您可以通过更改NSDateFormatter对象来修改date格式

 -(NSString*) getOrdinalDateString:(NSDate*)date { NSString* string=@""; NSDateComponents *components = [[NSCalendar currentCalendar] components: NSCalendarUnitDay fromDate:date]; if(components.day == 1 || components.day == 21 || components.day == 31) string = @"st"; else if (components.day == 2 || components.day == 22) string = @"nd"; else if (components.day == 3 || components.day == 23) string = @"rd"; else string = @"th"; NSDateFormatter *dateFormatte = [[NSDateFormatter alloc] init]; [dateFormatte setFormatterBehavior:NSDateFormatterBehavior10_4]; [dateFormatte setDateFormat:[NSString stringWithFormat:@"d'%@' MMMM yyyy",string]]; NSString *dateString = [dateFormatte stringFromDate:date]; return dateString; } 

一个干净的Swift版本(仅限英文版本):

 func ordinal(number: Int) -> String { if (11...13).contains(number % 100) { return "\(number)th" } switch number % 10 { case 1: return "\(number)st" case 2: return "\(number)nd" case 3: return "\(number)rd" default: return "\(number)th" } } 

可以作为Int的扩展来完成:

 extension Int { func ordinal() -> String { return "\(self)\(ordinalSuffix())" } func ordinalSuffix() -> String { if (11...13).contains(self % 100) { return "th" } switch self % 10 { case 1: return "st" case 2: return "nd" case 3: return "rd" default: return "th" } } } 

以下示例演示如何处理任何数字。 它在c#中,但是它可以很容易地转换成任何语言。

http://www.bytechaser.com/en/functions/b6yhfyxh78/convert-number-to-ordinal-like-1st-2nd-in-c-sharp.aspx

有一个简单的解决scheme

 let formatter = NumberFormatter() formatter.numberStyle = .ordinal let first = formatter.string(from: 1) let second = formatter.string(from: 2) let tenth = formatter.string(from: 10) let oneThousandAndFirst = formatter.string(from: 1001) 

参考: hackingwithswift.com

这里有一个Swift解决scheme,循环遍历用户的首选语言,直到find一个具有已知规则(这很容易添加)的序数:

 extension Int { var localizedOrdinal: String { func ordinalSuffix(int: Int) -> String { for language in NSLocale.preferredLanguages() as [String] { switch language { case let l where l.hasPrefix("it"): return "°" case let l where l.hasPrefix("en"): switch int { case let x where x != 11 && x % 10 == 1: return "st" case let x where x != 12 && x % 10 == 2: return "nd" case let x where x != 13 && x % 10 == 3: return "rd" default: return "st" } default: break } } return "" } return "\(self)" + ordinalSuffix(self) } } 

这里的许多解决scheme不能处理更高的数字,如112.这是一个简单的方法来做到这一点。

 for(int i=0;i<1000;i++){ int n = i; NSString* ordinal = @"th"; if(n%10==1 && n%100!=11) ordinal = @"st"; if(n%10==2 && n%100!=12) ordinal = @"nd"; if(n%10==3 && n%100!=13) ordinal = @"rd"; NSLog(@"You are the %d%@",i,ordinal); } 

下面是英语的一个简短的Int扩展,它也可以正确地解释和显示负整数:

 extension Int { func ordinal() -> String { let suffix: String! // treat negative numbers as positive for suffix let number = (self < 0 ? self * -1 : self) switch number % 10 { case 0: suffix = self != 0 ? "th" : "" case 1: suffix = "st" case 2: suffix = "nd" case 3: suffix = "rd" default: suffix = "th" } return String(self) + suffix } } 
 - (NSString *) formatOrdinalNumber:(NSInteger )number{ NSString *result = nil; //0 remains just 0 if (number == 0) { result = @"0"; } //test for number between 3 and 21 as they follow a //slightly different rule and all end with th else if (number > 3 && number < 21) { result = [NSString stringWithFormat:@"%ld th",(long)number]; } else { //return the last digit of the number eg 102 is 2 NSInteger lastdigit = number % 10; switch (lastdigit) { case 1: result = [NSString stringWithFormat:@"%ld st",(long)number]; break; case 2: result = [NSString stringWithFormat:@"%ld nd",(long)number]; break; case 3: result = [NSString stringWithFormat:@"%ld rd",(long)number]; break; default: result = [NSString stringWithFormat:@"%ld th",(long)number]; } } return result; } 

– 斯威夫特4 –

  let num = 1 let formatter = NumberFormatter() formatter.numberStyle = .ordinal let day = formatter.string(from: NSNumber(value: num)) print(day!) result - 1st 

这是我的蛮力实施,取得date的NSString *表示并返回序号值。 我觉得阅读起来要容易得多。

 NSDictionary *ordinalDates = @{ @"1": @"1st", @"2": @"2nd", @"3": @"3rd", @"4": @"4th", @"5": @"5th", @"6": @"6th", @"7": @"7th", @"8": @"8th", @"9": @"9th", @"10": @"10th", @"11": @"11th", @"12": @"12th", @"13": @"13th", @"14": @"14th", @"15": @"15th", @"16": @"16th", @"17": @"17th", @"18": @"18th", @"19": @"19th", @"20": @"20th", @"21": @"21st", @"22": @"22nd", @"23": @"23rd", @"24": @"24th", @"25": @"25th", @"26": @"26th", @"27": @"27th", @"28": @"28th", @"29": @"29th", @"30": @"30th", @"31": @"31st" };