使用NSNumberFormatter生成小数后带尾随零的数字

时间:2014-10-28 05:57:45

标签: ios swift double nsnumberformatter nslocale

在Swift中,你如何创建一个NSNumberFormatter来保留小数点后的尾随零(12.000),同时还生成一个适合当前区域设置的数字?

我当前的代码和示例输出:

let formatter = NSNumberFormatter()
formatter.numberStyle = .DecimalStyle
formatter.locale = NSLocale.currentLocale()
formatter.maximumFractionDigits = 10

var doubleNumString = "12.0"
println(formatter.numberFromString(doubleNumString)) //in English it prints 12, want it to print 12.0

var doubleNumString = "12.000"
println(formatter.numberFromString(doubleNumString)) //prints 12, want it to print 12.000

var doubleNumString = "12.125"
println(formatter.numberFromString(doubleNumString)) //prints 12.125 as expected

var doubleNumString = "1234"
println(formatter.numberFromString(doubleNumString)) //prints 1,234 as expected

我已经对它进行了编码,如果字符串以小数结尾("12."),则它不会使用此格式化程序生成数字,而只是显示数字然后显示十进制(但我需要改进它,因为有些语言从右到左阅读。)

一种解决方案是检查字符串是否包含句点,如果是,请检查其后面的所有数字是否为0,如果是,则不要通过数字格式化程序运行它而只运行int通过格式化程序的值然后追加/前置小数后跟适当的0到数。

有更好/更清洁的解决方案吗?

2 个答案:

答案 0 :(得分:2)

如Martin R所述,您可以将minimumFractionDigitsmaximumFractionDigits设置为相同的数字,这将强制始终显示多个小数位。要知道要显示多少,您需要将小数点后的子字符串带到结尾并计算其元素。要知道所有小数位是否为0,我创建了一个辅助方法,将该子字符串转换为数字,如果它等于0,那么你知道它们都是0。

不幸的是,您需要根据原始字符串编号使用几个不同的NSNumberFormatter将字符串转换为本地化的数字。因此,如果它确实包含一个小数,并且它后面的所有内容都是0,那么您需要创建一个不同的格式化程序,将字符串转换为数字,然后将该数字转换为字符串,以便根据用户的语言环境显示它。否则,您只需使用原始数字格式化程序。

答案 1 :(得分:-1)

此功能可满足您的要求。通过相同的&来自语言环境(例如en_US)

+ (NSString*) stringForString:(NSString*) string forLocale:(NSString*) toLocaleCode fromLocal:(NSString*) fromLocaleCode {

    NSLocale *fromLocale = [[NSLocale alloc] initWithLocaleIdentifier:fromLocaleCode];
    NSNumberFormatter *sourceFormatter = [[NSNumberFormatter alloc] init];
    [sourceFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
    [sourceFormatter setUsesGroupingSeparator:NO];
    [sourceFormatter setLocale:fromLocale];
    NSNumber *localizedNumber = [sourceFormatter numberFromString:string];

    if (!localizedNumber) {
        return string;
    }

    NSLocale *toLocale = [[NSLocale alloc] initWithLocaleIdentifier:toLocaleCode];

    NSNumberFormatter *destinationFormatter  = [[NSNumberFormatter alloc] init];
    [destinationFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
    [destinationFormatter setUsesGroupingSeparator:NO];
    [destinationFormatter setLocale:toLocale];
    NSString *localizedString = [destinationFormatter stringFromNumber:localizedNumber];

    //add the zeros which were dropped because of the sourceDecimalString number conversion e.g. 0.20 is converted to 0.2

    if (localizedString.length < string.length) {
        NSRange rangeOfDecimal = [string rangeOfString:sourceFormatter.decimalSeparator];
        if (rangeOfDecimal.location != NSNotFound) {
            NSString* sourceDecimalString = [string substringFromIndex:rangeOfDecimal.location];


            rangeOfDecimal = [localizedString rangeOfString:destinationFormatter.decimalSeparator];
            if (rangeOfDecimal.location != NSNotFound) {
                NSString* destinationDecimalString = [localizedString substringFromIndex:rangeOfDecimal.location];

                if (destinationDecimalString.length <  sourceDecimalString.length) {
                    int difference = sourceDecimalString.length - destinationDecimalString.length;
                    int toalDecimalDigits = (destinationDecimalString.length - 1) + difference; //-1 to remove '.'

                    destinationFormatter.minimumFractionDigits = toalDecimalDigits;
                    destinationFormatter.maximumFractionDigits = toalDecimalDigits;

                    localizedString = [destinationFormatter stringFromNumber:localizedNumber];
                }
            }
            else{//this indicates no decimal separator in the return string
                int toalDecimalDigits = (sourceDecimalString.length - 1); //-1 to remove '.'

                destinationFormatter.minimumFractionDigits = toalDecimalDigits;
                destinationFormatter.maximumFractionDigits = toalDecimalDigits;

                localizedString = [destinationFormatter stringFromNumber:localizedNumber];
            }

        }
    }

    return localizedString;
}