NSDecimalNumber decimalNumberWithString:忽略当前语言环境 [英] NSDecimalNumber decimalNumberWithString: ignores current locale

查看:176
本文介绍了NSDecimalNumber decimalNumberWithString:忽略当前语言环境的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据文档, [NSDecimalNumber decimalNumberWithString:] 应使用locale十进制分隔符:


NSDecimalSeparator是否是一个句点(例如,在美国使用
)或逗号(例如在法国使用)
取决于缺省值


但是当我尝试时,此代码:

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

给予...

  100 
100.1

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



(我知道我可以使用[NSDecimalNumber decimalNumberWithString:locale:]强制的行为,所以这个问题是:

解决方案

NSDecimalNumber是什么意思?只是数字类型数据的存储类。它在你传递它的字符串上运行一个解析器(NSNumberFormatter)来创建它的数字。第二个日志语句工作原理更好的原因是因为第一个日志语句使用默认数字格式区域设置(它看起来像是en_US,但我无法验证这一点,查看编辑打破更多信息。)解析,100,1不是有效的数字,所以非数字部分被剥离。



当NSLog()为NSDecimalNumber时,它只需调用 -



如果要打印格式正确的数字,请使用

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。






编辑



Ok,我对此做了一些研究。



在GNUStep中,它最终使用 NSDecimalSeparator NSUserDefaults (快速浏览他们的代码)。



我发现以下没有影响默认解析行为,就我所知:


  1. NSDecimalSeparator 中的

  2. c $ c> NSUserDefaults 。 $ $ c>。

  3. CFBundleDevelopmentRegion 设置的值。

  4. 环境的 LANG / LC_ALL / etc ...值。

  5. + [NSLocale systemLocale]

显然不是 + [NSLocale currentLocale] ,因为此问题源自当前语言环境没有效果。


According to the documentation, [NSDecimalNumber decimalNumberWithString:] should use the locale decimal separator:

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.

But when I try it, this code:

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

Gives...

100
100.1

...as output on both iOS 5 and iOS 6. I've tried with Swedish and French as regional settings as both these countries use comma (,) as decimal separator.

Shouldn't the output be the same?

(I know I can use [NSDecimalNumber decimalNumberWithString:locale:] to force the behavior, so this question is not about finding an alternative, just if this is a bug or I'm doing something wrong)

解决方案

NSDecimalNumber is simply a storage class for number-type data. It's running a parser (NSNumberFormatter) on the string you pass it to create its number. The reason your second log statement works "better" is because the first one is using the default number format locale (it looks like it's en_US, but I can't verify this, see the edit blow for more information.) to parse, and "100,1" isn't a valid number so the "non-number" part gets stripped off. By specifying a locale that uses "," decimal separators it's capturing the full number properly.

When you NSLog() an NSDecimalNumber it's simply calling -description, which has no locale context and can print, more or less, whatever it wants.

If you want to print properly formatted numbers use NSNumberFormatter like so:

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]);

Or, briefly

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

if you just want to use the current locale.

In summary:

  1. NSDecimalNumber is just storage. Logging it does not reflect anything about locale.
  2. In order to get NSDecimalNumber to store a number properly, its locale needs to match the locale of the expected input (-[NSLocale currentLocale] is a good choice here).
  3. In order to display numbers formatted correctly for a given locale, use NSNumberFormatter.


Edit:

Ok, I've done some more research on this.

In GNUStep it looks like it ends up using the value for NSDecimalSeparator in NSUserDefaults (from a quick browse of their code).

Doing some experimentation I've found that none of the following affect the default parsing behavior, as far as I can tell:

  1. NSDecimalSeparator in NSUserDefaults.
  2. AppleLocale in NSUserDefaults.
  3. NSLocaleCode in NSUserDefaults.
  4. The value set for CFBundleDevelopmentRegion.
  5. The Environment's LANG/LC_ALL/etc... values.
  6. +[NSLocale systemLocale].

And obviously it is not +[NSLocale currentLocale], as this question stems from the fact that the current locale has no effect.

这篇关于NSDecimalNumber decimalNumberWithString:忽略当前语言环境的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆