问题
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