0

I am writting CurrencyNumberFormatter that will take String or NSNumber and convert it to expected result with respect of current Locale.

This is my solution.

final class CurrencyNumberFormatter {
    /// Locale of a `CurrencyNumberFormatter`.
    var locale: Locale
    /// numberFormatter of a `CurrencyNumberFormatter`.
    private var numberFormatter: NumberFormatter
    /// Initializes a `CurrencyNumberFormatter` with a `Locale`.
    init(locale: Locale = .current) {
        self.locale = locale
        self.numberFormatter = NumberFormatter()
        self.numberFormatter.locale = self.locale
        self.numberFormatter.numberStyle = .currency
        self.numberFormatter.isLenient = true
    }
    /// Converts a String to a `NSumber`.
    ///
    /// - Parameters:
    ///   - string: string to convert.
    /// - Returns: `NSumber` represenation.
    func number(from string: String) -> NSNumber? {
        return self.numberFormatter.number(from: string)
    }
    /// Converts a NSumber to a `String`.
    ///
    /// - Parameters:
    ///   - number: nsnumber to convert.
    /// - Returns: `NSumber` represenation.
    func string(from number: NSNumber) -> String? {
        return self.numberFormatter.string(from: number)
    }
}

Usage:

let currensy =  CurrencyNumberFormatter()
currensy.number(from: "1000.25")  // 1000.25
currensy.number(from: "1,000.25") // 1000.25
currensy.number(from: "1.000,25") // nil  -> 1000.25
currensy.number(from: "1'000,25") // nil  -> 1000.25
currensy.number(from: ",25")      // 25   -> 0.25
currensy.number(from: ".25")      // 0.25

How can I handle cases with "1.000,25", "1'000,25" , ",25" ?

Oleg Gordiichuk
  • 15,240
  • 7
  • 60
  • 100
  • 1
    None of your examples are currency, they are simple decimals formatted in different locales. – rmaddy Feb 09 '18 at 23:45
  • @rmaddy In this example I remove part with currency symbols to highlight issue. In my case user can paste info $1'000,25 and it is in US locale. – Oleg Gordiichuk Feb 09 '18 at 23:47
  • As I said, the numbers use different locales. You only attempt to use the current user’s locale. – rmaddy Feb 09 '18 at 23:49
  • @OlegGordiichuk That should be handled by the `NumberFormatter` based on the locale. Or are you looking to accept those values in _all_ locales? (Also, it's "Currency", not "Currensy") – Itai Ferber Feb 09 '18 at 23:49
  • @ItaiFerber yes you are right I am searching way how can I check value in all locales. Thx for typo. But is It efficient to check all locales ? – Oleg Gordiichuk Feb 09 '18 at 23:50
  • @OlegGordiichuk What do you expect to have happen when someone types in "1,000" or "1.000"? "1,000" in my locale means 10^3 while "1.000" means 1^1, vs. for someone in a different locale, the expectations could be swapped. – Itai Ferber Feb 09 '18 at 23:52
  • @OlegGordiichuk Honestly, it would be best to leave things localized as they are. It would be _really_ confusing for me to enter "$1,000" and have that be parsed as "$1", or type in "$1.000" and have it be parsed as "$1000"... – Itai Ferber Feb 09 '18 at 23:53
  • @ItaiFerber In my case I need to convert "$1,000" to NSNumber that is 1000. So the info "1'000,25" -> 1000.25 – Oleg Gordiichuk Feb 09 '18 at 23:55
  • @OlegGordiichuk Replace all occurrences of `,` and `'` with `.` and then remove all but the last one. This is going to be wrong for many locales, but if you don't care... – Itai Ferber Feb 09 '18 at 23:57
  • @ItaiFerber but if I set only for example US locale and will try to prepare all string to US locale format I will receive clear NSNumber? – Oleg Gordiichuk Feb 09 '18 at 23:59
  • https://stackoverflow.com/questions/29782982/how-to-input-currency-format-on-a-text-field-from-right-to-left-using-swift/29783546?s=1|16.9905#29783546 – Leo Dabus Feb 10 '18 at 00:01
  • @OlegGordiichuk I'm not sure what you mean by that. If the user locale doesn't matter and you're looking to parse these strings in the same way in _all_ locales, just get rid of the `Locale` altogether. Set it to `en_US_POSIX`, convert the strings to US format always, and parse like that. – Itai Ferber Feb 10 '18 at 00:01
  • @ItaiFerber I got this thx for help. – Oleg Gordiichuk Feb 10 '18 at 00:02
  • @LeoDabus I will take look thx for help. – Oleg Gordiichuk Feb 10 '18 at 00:03
  • @OlegGordiichuk Note that not all countries currencies have fractional digits. The link I posted will consider the locale when determining the number of fraction digits – Leo Dabus Feb 10 '18 at 00:04

0 Answers0