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

根据文档, [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:]来强制行为,所以这个问题不是find一个替代scheme,只是如果这是一个错误,或者我做错了什么)

NSDecimalNumber只是一个数字型数据的存储类。 它正在运行一个parsing器(NSNumberFormatter)的string,你传递它来创build它的编号。 你的第二个日志语句工作“更好”的原因是因为第一个使用默认的数字格式语言环境(它看起来像是 en_US,但我无法validation这一点, 请参阅编辑打击了解更多信息 ) “100,1”不是一个有效的数字,所以“非数字”部分被剥离。 通过指定使用“,”十进制分隔符的语言环境,它将正确捕获整个数字。

当你NSLog()一个NSDecimalNumber它只是调用-description ,它没有语言环境上下文,可以打印,或多或less,无论它想要的。

如果你想打印正确格式的数字使用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只是存储。 logging它并不反映任何有关区域设置。
  2. 为了让NSDecimalNumber正确存储一个数字,它的语言环境需要匹配预期input的语言环境(在这里-[NSLocale currentLocale]是个不错的select)。
  3. 为了显示给定区域设置正确格式的数字,请使用NSNumberFormatter。

编辑:

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

在GNUStep中,它看起来像是在NSUserDefaults使用NSDecimalSeparator的值(通过快速浏览代码)。

做一些实验,我发现以下都不影响默认的parsing行为,据我所知:

  1. NSUserDefaults NSDecimalSeparator
  2. NSUserDefaults中的NSUserDefaults
  3. NSUserDefaults NSLocaleCode
  4. CFBundleDevelopmentRegion设置的值。
  5. 环境的LANG / LC_ALL / etc …值。
  6. +[NSLocale systemLocale]

显然这不是+[NSLocale currentLocale] ,因为这个问题源于当前的语言环境没有任何作用。