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 用于 2 个小数位

使用 NSNumberFormatter 循环中的 Objective C 自动释放

NSNumberFormatter 将浮点字符串格式化为整数

NSNumberformatter 添加额外的零