NSDecimalNumber decimalNumberWithString:忽略当前的语言环境

时间:2013-03-20 20:48:45

标签: ios objective-c cocoa-touch nsdecimalnumber

根据文档,[NSDecimalNumber decimalNumberWithString:]应使用区域设置小数分隔符:

  

NSDecimalSeparator是否为句点(例如,使用时)   在美国)或逗号(例如在法国使用)   取决于默认的语言环境。

但是当我尝试时,这段代码:

NSLog(@"%@", [NSDecimalNumber decimalNumberWithString:@"100,1"]);
NSLog(@"%@", [NSDecimalNumber decimalNumberWithString:@"100,1" locale:NSLocale.currentLocale]);

...给出

100
100.1

...作为iOS 5和iOS 6的输出。我尝试使用瑞典语和法语作为区域设置,因为这两个国家都使用逗号(,)作为小数点分隔符。

输出不应该相同吗?

(我知道我可以使用[NSDecimalNumber decimalNumberWithString:locale:]强制执行该行为,所以这个问题不是关于寻找替代方案,只是如果这是一个错误或者我做错了什么)

1 个答案:

答案 0 :(得分:7)

NSDecimalNumber只是数字类型数据的存储类。它在你传递它的字符串上运行一个解析器(NSNumberFormatter)来创建它的号码。你的第二个日志语句工作“更好”的原因是因为第一个使用默认的数字格式区域设置(看起来像它的en_US,但我无法验证这一点,看到编辑打击更多信息。)解析,“100,1”不是有效数字,因此“非数字”部分被剥离。通过指定使用“,”十进制分隔符的区域设置,它可以正确捕获完整数字。

当您NSLog()NSDecimalNumber时,它只是调用-description,它没有区域设置上下文,可以或多或少地打印它想要的任何内容。

如果要打印格式正确的数字,请使用NSNumberFormatter,如下所示:

NSDecimalNumber *number = [NSDecimalNumber decimalNumberWithString:@"100.1"];

NSLog(@"%@", number);

NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];

[formatter setNumberStyle:NSNumberFormatterDecimalStyle];

NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"fr_FR"];

[formatter setLocale:locale];

NSLog(@"%@", [formatter stringFromNumber:number]);

或者,简单地

NSDecimalNumber *number = [NSDecimalNumber decimalNumberWithString:@"100.1"];
NSLog(@"%@", [NSNumberFormatter localizedStringFromNumber:number numberStyle:NSNumberFormatterDecimalStyle]);

如果您只想使用当前的区域设置。

总结:

  1. NSDecimalNumber只是存储。记录它并不反映任何有关区域设置的信息。
  2. 为了让NSDecimalNumber正确存储一个数字,它的语言环境需要匹配预期输入的语言环境(-[NSLocale currentLocale]这里是个不错的选择。)
  3. 为了显示针对给定语言环境正确格式化的数字,请使用NSNumberFormatter。

  4. 修改

    好的,我已经对此做了更多的研究。

    在GNUStep中,它似乎最终使用NSDecimalSeparatorNSUserDefaults的值(快速浏览其代码)。

    做一些实验我发现以下所有内容都不会影响默认的解析行为,据我所知:

      {li> NSDecimalSeparator NSUserDefaults。 {li> AppleLocale NSUserDefaults。 {li> NSLocaleCode NSUserDefaults
    1. CFBundleDevelopmentRegion
    2. 设置的值
    3. 环境的LANG / LC_ALL / etc ...值。
    4. +[NSLocale systemLocale]
    5. 显然它不是+[NSLocale currentLocale],因为这个问题源于当前的语言环境没有效果。