ios - NSDecimalNumber decimalNumberWithString : ignores current locale

标签 ios objective-c cocoa-touch nsdecimalnumber

根据文档,[NSDecimalNumber decimalNumberWithString:] 应该使用语言环境小数点分隔符:

Whether the NSDecimalSeparator is a period (as is used, for example, in the United States) or a comma (as is used, for example, in France) depends on the default locale.

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

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

给...

100
100.1

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

输出不应该一样吗?

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

最佳答案

NSDecimalNumber 只是一个数字类型数据的存储类。它在您传递给它的字符串上运行解析器 (NSNumberFormatter) 以创建其编号。你的第二个日志语句工作“更好”的原因是因为第一个使用默认数字格式区域设置(它看起来它是en_US,但我无法验证这一点,查看编辑blow for more information.) 进行解析,并且“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 只是存储。记录它不会反射(reflect)有关语言环境的任何信息。
  2. 为了让 NSDecimalNumber 正确存储数字,它的区域设置需要与预期输入的区域设置相匹配(-[NSLocale currentLocale] 是一个不错的选择)。
  3. 为了显示针对给定语言环境正确格式化的数字,请使用 NSNumberFormatter。

编辑:

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

在 GNUStep 中,看起来它最终使用了 NSUserDefaults 中的 NSDecimalSeparator 的值(通过快速浏览他们的代码)。

在做一些实验后,我发现以下任何一项都不会影响默认的解析行为,据我所知:

  1. NSDecimalSeparatorNSUserDefaults 中。
  2. AppleLocaleNSUserDefaults 中。
  3. NSLocaleCodeNSUserDefaults 中。
  4. CFBundleDevelopmentRegion 设置的值。
  5. 环境的 LANG/LC_ALL/etc... 值。
  6. +[NSLocale systemLocale]

而且显然不是+[NSLocale currentLocale],因为这个问题源于当前语言环境没有影响的事实。

关于ios - NSDecimalNumber decimalNumberWithString : ignores current locale,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15534431/

相关文章:

ios - 当虚拟键盘在 Mobile Safari 中打开时,如何阻止我的固定导航像这样移动?

ios - Swift SKSpriteNode 位置 iPhone V iPad

iOS 游戏开发

android - 从 Android 和 iOS 中的相同代码库开发多个应用程序

ios - 如何在 UITableView 原型(prototype)单元格上设置自定义 UILabel 文本

objective-c - 将UISliders值显示为%

objective-c - 检测 Mac OS X 空间中的空间何时发生变化

iphone - 如何用不同的 UITextField 覆盖 UITextField

iphone - 如何准确检查表面平整度

ios - 从 UIFont 或 .ttf 文件中获取字体的每个字符(带形状)