NSNumberFormatter numberFromString 为货币样式格式化程序返回 0
Posted
技术标签:
【中文标题】NSNumberFormatter numberFromString 为货币样式格式化程序返回 0【英文标题】:NSNumberFormatter numberFromString returns 0 for currency style formatter 【发布时间】:2011-11-22 22:54:36 【问题描述】:我尝试测试以下代码以从货币样式格式化的 UITextField 中获取双精度值(例如:$ 30,034.12 => 30034.12):
// Init and configure formatter
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[formatter setMaximumFractionDigits:2];
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"us_US"];
[formatter setLocale:locale];
[formatter setGroupingSize:3];
[formatter setUsesGroupingSeparator:YES];
[formatter setGroupingSeparator:@","];
[formatter setAllowsFloats:YES];
// Get a formatted string using the local currency formatter and then get a double
// vice-versa
NSNumber *amount = [NSNumber numberWithDouble:30034.12];
NSString *amountString = [formatter stringFromNumber:amount];
// Output here OK : @"$ 30,034.12"
double amountDouble = [[formatter numberFromString:amountString] doubleValue];
// Output here NOT OK : 0
有人遇到过/解决过同样的问题吗?
谢谢!
更新:
@DanielBarden 和其他人。实际上,为了简化帖子,我没有包含指定从何处获取字符串的部分:文本字段。其实代码结束前的那一行应该是:
NSString *amountString = [textField text];
并且此文本字段先前已使用其他方法的以下代码格式化(货币样式使用相同的格式化程序配置):
// Init fromatter with style $ XXX,XXX.yy
NSNumberFormatter* formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[formatter setMaximumFractionDigits:2];
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"us_US"];
[formatter setLocale:locale];
[formatter setGroupingSize:3];
[formatter setGroupingSeparator:@","];
[formatter setUsesGroupingSeparator:YES];
// Get the float value of the text field and format it
textField.text = [formatter
stringFromNumber:[NSNumber
numberWithDouble:[textField.text
floatValue]]];
现在的问题是,当我执行 NSLog 时,我得到完全相同的字符串,但是当我将它们逐个字符与循环进行比较时,它表示 $ 之后的空间是文本字段上的“真实空间”,并且初始字符串上的不同符号(amountString 是我在初始帖子中尝试测试的那个...)。编码问题?
【问题讨论】:
您能否显示您正在拨打的NSLog
电话?
这段代码对我来说很好用。你是怎么调试的?我正在使用 NSLog ("%f", amountDouble);
我相信问题出在 $ 符号上。由于您的字符串具有符号,因此在尝试获取该符号的双精度值时,它将给出一个大 0。
@DanielBarden PengOne 和 A Salcedo,我在原帖末尾添加了更详细的解释,正在更新中。我仍然无法解决问题。非常感谢您的帮助!
【参考方案1】:
我唯一能想到的是 $ 符号的问题。将格式化程序设置为货币样式需要 $ 符号,如果它不存在于字符串中,则返回 0
【讨论】:
嗯 ...当我尝试更深入地调试它时,我意识到我实际上遇到了将 $ 符号与数值分隔开的空格的问题。我怀疑是编码问题,但仍然没有解决。我在原始帖子的末尾添加了更详细的解释,以防您有时间阅读。非常感谢!【参考方案2】:代码对我来说是正确的,Xcode 同意我的看法。我在您缺少的两行中添加了:
NSLog(@"%@",amountString);
NSLog(@"%f",amountDouble);
并且输出是正确的。我建议你检查你是如何记录这些值的。
【讨论】:
是的,确实这段代码工作正常,我没有想到包含我从文本字段中获取金额字符串的原始代码。双精度先前使用相同的格式化程序配置进行格式化,并影响到文本字段。从那里我试图以另一种方式完成任务。我在“更新:”下的原始帖子末尾添加了有关该问题的更详细说明。我怀疑存在编码问题,但仍在处理中。你有什么线索吗?非常感谢!【参考方案3】:问题是formatter.currencySymbol
可能不是正确的“$”,即“USD”。所以解决方案是formatter.currencySymbol = "$"
let localeID = "th_TH" // Thailand
let correctCurrencySymbol = "฿" // "$" for US dollar
let formatter = NumberFormatter()
formatter.locale = Locale(identifier:localeID)
formatter.numberStyle = .currencyStyle
let currencySymbol = formatter.currencySymbol // "฿" for ios 13, "THB" for iOS 12 or earlier versions
print("currencySymbol: \(currencySymbol)")
if (currencySymbol != correctCurrencySymbol) // "USD" for US dollar
formatter.currencySymbol = correctCurrencySymbol
print("【Error】fix formatter.currencySymbol from \(currencySymbol) to \(correctCurrencySymbol)")
let amount = -30.12
if let str = formatter.string(for: amount)
print("Currency format of \(amount) is \(str)") // -฿30.12
// works OK until set correctCurrencySymbol
if let amount1 = formatter.number(from: str)?.decimalValue
print("Comvert back to number is \(amount1)") // -30.12
【讨论】:
以上是关于NSNumberFormatter numberFromString 为货币样式格式化程序返回 0的主要内容,如果未能解决你的问题,请参考以下文章
NSNumberFormatter - 获取货币代码的货币符号
NSNumberFormatter、NSDecimalNumber 和科学记数法
使用 NSNumberFormatter 循环中的 Objective C 自动释放