NSNumberFormatter and 'th' 'st' 'nd' 'rd' (ordinal) number endings

前端 未结 20 1222
粉色の甜心
粉色の甜心 2020-12-03 00:38

Is there a way to use NSNumberFormatter to get the \'th\' \'st\' \'nd\' \'rd\' number endings?

EDIT:

Looks like it does not exist. Here\'s what I\'m using.

相关标签:
20条回答
  • 2020-12-03 01:43
    - (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 e.g. 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;
    }
    
    0 讨论(0)
  • 2020-12-03 01:44

    Since the question asked for a number formatter, here's a rough one I made.

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

    and the implementation:

    //
    //  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
    

    Instantiate this as an Interface Builder object and attach the Text Field's formatter outlet to it. For finer control (such as setting maximum and minimum values, you should create an instance of the formatter, set the properties as you wish and attach it to text field using it's setFormatter: method.

    You can download the class from GitHub (including an example project)

    0 讨论(0)
提交回复
热议问题