Swift convert Currency string to double - swift

I have a string, "$4,102.33" that needs to be converted to double. This will always be US. My only way is a hack to strip out the $ and , and then convert to double. Seems like NSFormatter only lets me convert TO a currency and not from it. Is there a built-in function or better way than just removing the $ and ,? prior to converting it to double?

NumberFormatter can convert to and from string. Also Double cannot represent certain numbers exactly since it's based 2. Using Decimal is slower but safer.
let str = "$4,102.33"
let formatter = NumberFormatter()
formatter.numberStyle = .currency
if let number = formatter.number(from: str) {
let amount = number.decimalValue
print(amount)
}

To convert from String to NSNumber for a given currency is easy:
let formatter = NumberFormatter()
formatter.numberStyle = .currency
formatter.locale = Locale(identifier: "en_US")
let number = formatter.number(from: string)
To get your number as a Double or as a Decimal (preferred) is then direct:
let doubleValue = number?.doubleValue
let decimalValue = number?.decimalValue

Related

iOS Swift - Convert double to String precision last value rounded to next value

Example value : 3.00035358. i am trying to convert double value to string
Method 1:
let num = NSNumber(value:self)
let formatter : NumberFormatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.minimumFractionDigits = 4
let str = formatter.string(from: num)!
return str
method2 :
extension Double {
var stringWithoutZeroFraction: String {
return truncatingRemainder(dividingBy: 1) == 0 ? String(d: "%.0f", self) : String(format:"%.4f", self)
}
}
expecting output to be 3.003 but getting like 3.004. i do want my last digit to be rounded to next digit.how to fix tho issue.any help will be appricated.thanks in advance
If you use a NumberFormatter, you need to set the roundingMode to .floor to achieve truncating. Also, if you want to truncate, you probably want to set maximumFractionDigits instead of minimumFractionDigits.
extension Double {
var string: String {
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.maximumFractionDigits = 4
formatter.roundingMode = .floor
return formatter.string(for: self) ?? description
}
}
3.00035358.string // "3.0003"

How to convert NSNumber to String in Swift4?

How to convert an Array of NSNumber to Array of String in order to display the value in UITableView?
cell.textlabel.text = ?
Code:
var a = [68.208983, 6.373902, 1.34085, 3.974012, 110.484001,
61.380001, 1.325202, 0.8501030000000001, 0.8501030000000001,
0.8501030000000001, 3.647296, 1.28503]
just add
.stringValue
to your NSNumber variable
From what you posted is an array of Double if you don't annotate them explicitly. If the array you posted is as it is, then you need this:
let arrayOfDoubles = [68.208983, 6.373902, 1.34085, 3.974012, 110.484001, 61.380001, 1.325202, 0.8501030000000001, 0.8501030000000001, 0.8501030000000001, 3.647296, 1.28503]
let stringArrayOfDoubles = arrayOfDoubles.map { String($0) }
Or, if you explicitly annotate the type as [NSNumber] then you will need this:
let arrayOfNumbers: [NSNumber] = [68.208983, 6.373902, 1.34085, 3.974012, 110.484001, 61.380001, 1.325202, 0.8501030000000001, 0.8501030000000001, 0.8501030000000001, 3.647296, 1.28503]
let stringArrayOfNumbers = arrayOfNumbers.map { $0.stringValue }
If you're going to display numeric data to the user, it's best to use a number formatter. That way your output will adapt to the formatting that your users are used to and expect based on their locale. It also allows you to configure how the numbers are presented (number of fraction digits, significant digits, rounding, etc.) without having to modify the numbers. For example, if you want to format a number as a decimal with two fraction digits, you would configure the formatter like this:
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.maximumFractionDigits = 2
Depending on the user's locale, the output (thousand separator, decimal separator, and even digits(!)) will vary:
formatter.locale = Locale(identifier: "en")
formatter.string(from: 12345.6789) // 12,345.68
formatter.string(from: 0.12345) // 0.12
formatter.locale = Locale(identifier: "sv")
formatter.string(from: 12345.6789) // 12 345,68
formatter.string(from: 0.12345) // 0,12
formatter.locale = Locale(identifier: "hi")
formatter.string(from: 12345.6789) // १२,३४५.६८
formatter.string(from: 0.12345) // ०.१२
formatter.locale = Locale(identifier: "ar")
formatter.string(from: 12345.6789) // ١٢٬٣٤٥٫٦٨
formatter.string(from: 0.12345) // ٠٫١٢
Other number styles can be used to format other types of numeric data like currency, percent, or ordinal numbers:
formatter.locale = Locale(identifier: "en")
formatter.numberStyle = .ordinal
formatter.string(from: 1) // 1st
formatter.string(from: 2) // 2nd
formatter.string(from: 3) // 3rd
formatter.string(from: 4) // 4th
Convert givent value in to String.
If given value is nil then it will return empty string.
class func toString(_ anything: Any?) -> String {
if let any = anything {
if let num = any as? NSNumber {
return num.stringValue
} else if let str = any as? String {
return str
}
}
return ""
}
Just Copy paste this method convert to string without crash issue
Thanks.

Why NSNumber do not respect locale decimalSeparator

I am using NumberFormatter to convert String to NSNumber with respect of the current locale.
My test locale is Sweden.
So the decimalSeparatorin my case is ","
This is NumberFormatter declaration.
let numberFormatter = NumberFormatter()
numberFormatter.locale = .current
numberFormatter.numberStyle = .decimal
numberFormatter.isLenient = true
Usage.
let number = numberFormatter.number(from:"1,01") // 1.01
But when I try to convert NSNumber back to string.
let stringNumber = number?.stringValue // 1.01
I receive wrong locale decimalSeparator.
Don't use stringValue to convert the number back to a string you wish to display to the user. Use your NumberFormatter to convert the number to a locale friendly string representation.
FYI - there is no need to set the number formatter's locale to .current since that is the default.

Unable to convert very small string value to decimal with NumberFormatter Swift4

I try to convert string "0.0004131955" to decimal/double/currency with NumberFormatter. It produces nil.
How to convert it?
My sample code is as below:
let formatter = NumberFormatter()
formatter.locale = Locale.current
formatter.numberStyle = .currency
formatter.minimumFractionDigits = 1
formatter.maximumFractionDigits = 15
formatter.usesGroupingSeparator = true
//number is nil here
if let number = formatter.number(from: "0.0004131955") {
let unitPrice = number.doubleValue
}
What am I doing wrong?
Remove the currency from numberStyle - copy to a playground to test
import UIKit
import PlaygroundSupport
let formatter = NumberFormatter()
formatter.locale = Locale.current
//formatter.numberStyle = .currency
formatter.minimumFractionDigits = 1
formatter.maximumFractionDigits = 15
formatter.usesGroupingSeparator = true
let number: NSNumber? = formatter.number(from: "0.0004131955")
let unitPrice: Double? = number?.doubleValue
HI #erdemgc for Number stlye Deciamal your code is working fine for me you can check console in below image
and for the currency you have to specify a currency style format you for Example i am attaching a image please take a look of below description

How to convert Long Double to String in swift

I would like to print data Double in Swift, but the output is always 4.444444444444e+24, not a real number.
How can I do that?
An even easier approach to format your Doubles without scientific notation would be to use String(format: "%.0f", data)
Note that Double cannot hold 44444444444444444.0 correctly, therefore you would probably get something like 44444444444444448 as output.
To get correct results you should use NSDecimalNumber, like this:
let decimalNumber = NSDecimalNumber(string: "44444444444444444.0")
print(decimalNumber.stringValue)
See if this helps you...
This code converts a number from scientific format to normal format
let numberFormatter = NumberFormatter()
numberFormatter.numberStyle = .decimal
let finalNumber = numberFormatter.number(from: "\(1e+07)")
print(finalNumber!)
This is the result: 10000000
#Skytect's answer is almost correct. It is just missing one step. Try the following code
let data1 : Double = 44444444444444444.0
let data2 : Double = 1000000.0
let data3 = data1 * data2
let numberFormatter = NumberFormatter()
numberFormatter.numberStyle = .decimal
let num = NSNumber(value: data3)
let finalNumber = numberFormatter.string(from: num)
print(finalNumber!)
More Class and Class func way
class Formatter {
static let numberFormatter: NumberFormatter = {
$0.minimumFractionDigits = 0
$0.maximumFractionDigits = 1
return $0
}(NumberFormatter())
class func string(from double: Double) -> String {
let nsNumber = NSNumber(value: double)
guard let formattedString = numberFormatter.string(from: nsNumber) else { fatalError("Should never happen") }
return formattedString
}
}
Usage
UITextField.text = Formatter.string(from: double)