将字符串转换为 NSDecimalNumber

Convert String to NSDecimalNumber

我尝试在此处将字符串转换为 NSDecimalNumber 我的代码:

class func stringToDecimal (dataToDecimal: String) -> NSDecimalNumber {

    let dataToDecimal = dataToDecimal.stringByReplacingOccurrencesOfString(",", withString: ".")
    print(dataToDecimal)
    let  decimalReturn = NSDecimalNumber(string: dataToDecimal)
    print(decimalReturn)

    if decimalReturn == NSDecimalNumber.notANumber(){
        return 0.00
    }
    return decimalReturn
}

首先我认为 , 可能是错误的,但即使是 .它不起作用。 第一个打印(转换前)显示例如 80,00 但打印(decimalReturn)仅显示 80

if 行只是检查结果是否不是数字。

使用 NSNumberFormatter 来解析您的输入。将其 generatesDecimalNumbers 属性 设置为 true:

let formatter = NumberFormatter()
formatter.generatesDecimalNumbers = true

下面是使用方法,如果你想在无法解析字符串时return0:

func decimal(with string: String) -> NSDecimalNumber {
    return formatter.number(from: string) as? NSDecimalNumber ?? 0
}

decimal(with: "80.00")

// Result: 80 as an NSDecimalNumber

默认情况下,格式化程序将查看设备的区域设置以确定小数点标记。你应该那样做。为了举例,我将强制使用法语语言环境:

// DON'T DO THIS. Just an example of behavior in a French locale.
formatter.locale = Locale(identifier: "fr-FR")

decimal(with: "80,00")
// Result: 80

decimal(with: "80.00")
// Result: 0

如果你真的想一直使用逗号作为小数点,你可以设置 decimalSeparator 属性:

formatter.decimalSeparator = ","

您从 String 创建 NSDecimalNumber 的方式没有任何问题。但是,如果您的本地数字格式是这样,您可能不必担心用句点替换逗号。

它打印 80 而不是 80,00 或 80.00 的原因是 print 只是使用了数字的 description 属性。如果你想自定义格式,你应该设置你自己的 NSNumberFormatter.

let number = NSDecimalNumber(string: "80.00")
print(number) // 80
let formatter = NSNumberFormatter()
formatter.minimumFractionDigits = 2
let string = formatter.stringFromNumber(number)
print(string) // 80.0

当服务器强制某些特定区域设置时使用它而不是 Locale.current 以免你想破损取决于用户的设置

extension String {
    var decimalFromServerString: NSDecimalNumber? {
        let parsed = NSDecimalNumber(string: self, locale: ru_ru_posix)
        if parsed == .notANumber {
            return nil
        }
        return parsed
    }
}

PS。如果你出于某种原因将区域设置设置为 en_US POSIX