4

I've converted a number into a currency formatted string (e.g. 2000 -> £2,000.00) using the NumberFormatter class. However I need a way of converting the formatted string back into a number (e.g. £2,000.00 -> 2000).

It turns out simply running it back through the formatter doesn't work and just produces nil. Does anyone know the best way to achieve this?

1
  • I believe there are some localization frameworks out there that will do this for you. Commented Feb 12, 2017 at 11:08

2 Answers 2

5

Swift 4: The following String extension helps to convert currency formatted strings to decimal or double. The method automatically identifies the number format for most common currencies.

The String has to be without currency symbol (€, $, £, ...):

For Example:

US formatted string: "11.233.39" -> 11233.39

European formatted string: "11.233,39" -> 11233.39

// String+DecimalOrDouble

extension String {   
    func toDecimalWithAutoLocale() -> Decimal? {
        let formatter = NumberFormatter()
        formatter.numberStyle = .decimal

        //** US,CAD,GBP formatted
        formatter.locale = Locale(identifier: "en_US")

        if let number = formatter.number(from: self) {
            return number.decimalValue
        }
        
        //** EUR formatted
        formatter.locale = Locale(identifier: "de_DE")

        if let number = formatter.number(from: self) {
           return number.decimalValue
        }
        
        return nil
    }
    
    func toDoubleWithAutoLocale() -> Double? {
        guard let decimal = self.toDecimalWithAutoLocale() else {
            return nil
        }

        return NSDecimalNumber(decimal:decimal).doubleValue
    }
}

Example tested in Playground:

import Foundation

//US formatted without decimal mark
str = "11233.3"
decimal = str.toDecimalWithAutoLocale() //11233.3
double = str.toDoubleWithAutoLocale() //11233.3

//EU formatted without decimal mark
str = "11233,3"
decimal = str.toDecimalWithAutoLocale() //11233.3
double = str.toDoubleWithAutoLocale() //11233.3

//US formatted with decimal mark
str = "11,233.3"
decimal = str.toDecimalWithAutoLocale() //11233.3
double = str.toDoubleWithAutoLocale() //11233.3

//EU formatted with decimal mark
str = "11.233,3"
decimal = str.toDecimalWithAutoLocale() //11233.3
double = str.toDoubleWithAutoLocale() //11233.3
Sign up to request clarification or add additional context in comments.

Comments

2

Fast trick:

let numString = String(number.characters.filter { "0123456789.".characters.contains($0) })           
let number = Double(numString)

1 Comment

this is not good. doesnt handle the obvious concern which is different ways to write a price (ie. "." vs ",")

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.