Convert String to NSDecimalNumber

HongKongTom picture HongKongTom · Nov 13, 2015 · Viewed 9k times · Source

I try to convert a String into a NSDecimalNumber here it my code:

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
}

First I thought that maybe the , is wrong but even with . it doesn't work. The first print (before converting) shows e.g 80,00 but the print(decimalReturn) shows only 80

the if line is the just to check if the result is not a number.

Answer

rob mayoff picture rob mayoff · Nov 13, 2015

Use an NSNumberFormatter to parse your input. Set its generatesDecimalNumbers property to true:

let formatter = NumberFormatter()
formatter.generatesDecimalNumbers = true

Here's how you use it, if you want to return 0 when the string can't be parsed:

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

decimal(with: "80.00")

// Result: 80 as an NSDecimalNumber

By default, the formatter will look at the device's locale setting to determine the decimal marker. You should leave it that way. For the sake of example, I'll force it to a French locale:

// 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

If you really want to always use a comma as the decimal mark, you can set the decimalSeparator property:

formatter.decimalSeparator = ","