iOS swift NumberFormatter decimal style localization

落爺英雄遲暮 提交于 2019-12-02 12:28:25

问题


I am working with NumberFormatter.Style.decimal I need 20000.23 should be 20,000.23 for that I create an extension

var NumerWithDecimalPoint : String{    
        if self != ""{

            let numberFormatter = NumberFormatter()
            if IS_PERSIAN{
                numberFormatter.locale = Locale(identifier: "fa_IR")
            }else{
                numberFormatter.locale = Locale(identifier: "EN")
            }
            numberFormatter.numberStyle = NumberFormatter.Style.decimal
            numberFormatter.maximumFractionDigits = 2
            numberFormatter.roundingMode = .floor

            let number = numberFormatter.number(from: self)
            let str = numberFormatter.string(from: number!)

            return str!
        }else{
            return ""
        }

    }

If work fine in en but crash in fa_IR let number = numberFormatter.number(from: self)


回答1:


Try this :

let Formatter: NumberFormatter = NumberFormatter()
Formatter.locale = Locale(identifier: "EN")
let number = Formatter.number(from: self)
let str = numberFormatter.string(from: number! )




回答2:


Your goal seems to be to convert a String representing a number in some unknown format into a String representing the same number nicely formatted in some specific language.

The cause of your crash is that if IS_PERSIAN is true, the attempt to parse an English number fails due to the Persian locale. And you try to force unwrap the nil number.

What you really need to do is try to parse "self" using various locales until you get a valid NSNumber result. Then convert that number back into a string using the desired locale.

The following updates to your code accomplish this:

extension String {
    var numerWithDecimalPoint : String{
        if self != ""{
            let numberFormatter = NumberFormatter()
            numberFormatter.numberStyle = .decimal
            numberFormatter.maximumFractionDigits = 2
            numberFormatter.roundingMode = .floor

            var number: NSNumber?
            if let num = numberFormatter.number(from: self) {
                number = num
            } else {
                numberFormatter.locale = Locale(identifier: "fa_IR")
                if let num = numberFormatter.number(from: self) {
                    number = num
                } else {
                    numberFormatter.locale = Locale(identifier: "en")
                    if let num = numberFormatter.number(from: self) {
                        number = num
                    }
                }
            }

            let str: String
            if let number = number {
                if IS_PERSIAN{
                    numberFormatter.locale = Locale(identifier: "fa_IR")
                }else{
                    numberFormatter.locale = Locale(identifier: "en")
                }
                if let res = numberFormatter.string(from: number) {
                    str = res
                } else {
                    str = "Can't convert \(number) to a string"
                }
            } else {
                str = "Can't convert \(self) to a number"
            }

            return str
        }else{
            return ""
        }
    }
}

This code tries to convert the original string to a number first using the user's locale. If that fails, it tries Persian. If that fails it tries English.




回答3:


Your problem is on decimal separator. It seems that standard Persian format use comma "," instead of point "." for decimal symbol. If you prefer to use English format, you have to define your decimal separator.

var NumerWithDecimalPoint : String{

        if !self.isEmpty{

            let numberFormatter = NumberFormatter()

            if IS_PERSIAN{
                numberFormatter.locale = Locale(identifier: "fa_IR")
            }else{
                numberFormatter.locale = Locale(identifier: "EN")
            }

            numberFormatter.decimalSeparator = "." //decimal separator
            numberFormatter.numberStyle = NumberFormatter.Style.decimal
            numberFormatter.maximumFractionDigits = 2
            numberFormatter.roundingMode = .floor

            if let number = numberFormatter.number(from: self) {
                return  numberFormatter.string(from: number) ?? ""
            }
        }
        return "Bad format number"
    }



回答4:


In the playground, I made sample code like this

let largeNumber = 1000000
let numberFormatter = NumberFormatter()
numberFormatter.locale = Locale(identifier: "fa")
numberFormatter.numberStyle = NumberFormatter.Style.decimal
numberFormatter.string(from: NSNumber(value: largeNumber))
print(numberFormatter.string(from: NSNumber(value: largeNumber))!)

result : "۱٬۰۰۰٬۰۰۰"

So if locale is "fa-IR", Should do not set locale



来源:https://stackoverflow.com/questions/43840222/ios-swift-numberformatter-decimal-style-localization

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!