如何将 Double 格式化为货币 - Swift 3
How to format a Double into Currency - Swift 3
我是 Swift 编程的新手,我一直在 Xcode 8.2 中创建一个简单的小费计算器应用程序,我在下面的 IBAction
中设置了我的计算。但是当我实际上 运行 我的应用程序并输入一个数量来计算(例如 23.45)时,它会出现超过 2 位小数。在这种情况下,如何将其格式化为 .currency
?
@IBAction func calculateButtonTapped(_ sender: Any) {
var tipPercentage: Double {
if tipAmountSegmentedControl.selectedSegmentIndex == 0 {
return 0.05
} else if tipAmountSegmentedControl.selectedSegmentIndex == 1 {
return 0.10
} else {
return 0.2
}
}
let billAmount: Double? = Double(userInputTextField.text!)
if let billAmount = billAmount {
let tipAmount = billAmount * tipPercentage
let totalBillAmount = billAmount + tipAmount
tipAmountLabel.text = "Tip Amount: $\(tipAmount)"
totalBillAmountLabel.text = "Total Bill Amount: $\(totalBillAmount)"
}
}
如果你想强制货币为 $,你可以使用这个字符串初始值设定项:
String(format: "Tip Amount: $%.02f", tipAmount)
如果你想让它完全依赖于设备的语言环境设置,你应该使用NumberFormatter
。这将考虑货币的小数位数以及正确定位货币符号。例如。双精度值 2.4 将 return es_ES 区域设置为“2,40 €”,jp_JP 区域设置为“¥ 2”。
let formatter = NumberFormatter()
formatter.locale = Locale.current // Change this to another locale if you want to force a specific locale, otherwise this is redundant as the current locale is the default already
formatter.numberStyle = .currency
if let formattedTipAmount = formatter.string(from: tipAmount as NSNumber) {
tipAmountLabel.text = "Tip Amount: \(formattedTipAmount)"
}
最好的方法是创建一个 NSNumberFormatter
。 (NumberFormatter
in Swift 3.)您可以请求货币,它会设置字符串以遵循用户的本地化设置,这很有用。
作为使用 NumberFormatter 的替代方法,如果您想强制使用美国格式的美元和美分字符串,您可以按以下方式格式化:
let amount: Double = 123.45
let amountString = String(format: "$%.02f", amount)
方法如下:
let currentLocale = Locale.current
let currencySymbol = currentLocale.currencySymbol
let outputString = "\(currencySymbol)\(String(format: "%.2f", totalBillAmount))"
第 1 行:您正在获取当前语言环境
第 2 行:您正在获取该语言环境的 currencySymbol。 ($、£ 等)
第 3 行:使用格式初始值设定项将 Double 截断为小数点后两位。
除了别人讨论的NumberFormatter
或者String(format:)
,你可以考虑使用Decimal
或者NSDecimalNumber
,自己控制四舍五入,避免浮动点问题。如果您正在做一个简单的小费计算器,那可能没有必要。但是,如果您要在一天结束时将小费相加,如果您不对数字进行四舍五入 and/or 使用十进制数进行计算,则可能会引入错误。
所以,继续配置格式化程序:
let formatter: NumberFormatter = {
let _formatter = NumberFormatter()
_formatter.numberStyle = .decimal
_formatter.minimumFractionDigits = 2
_formatter.maximumFractionDigits = 2
_formatter.generatesDecimalNumbers = true
return _formatter
}()
然后,使用十进制数:
let string = "2.03"
let tipRate = Decimal(sign: .plus, exponent: -3, significand: 125) // 12.5%
guard let billAmount = formatter.number(from: string) as? Decimal else { return }
let tip = (billAmount * tipRate).rounded(2)
guard let output = formatter.string(from: tip as NSDecimalNumber) else { return }
print("\(output)")
在哪里
extension Decimal {
/// Round `Decimal` number to certain number of decimal places.
///
/// - Parameters:
/// - scale: How many decimal places.
/// - roundingMode: How should number be rounded. Defaults to `.plain`.
/// - Returns: The new rounded number.
func rounded(_ scale: Int, roundingMode: RoundingMode = .plain) -> Decimal {
var value = self
var result: Decimal = 0
NSDecimalRound(&result, &value, scale, roundingMode)
return result
}
}
显然,您可以将上述所有“2 位小数”引用替换为适合您使用的货币的任何数字(或者可能使用小数位数的变量)。
你可以这样转换:这个函数转换为你保留 maximumFractionDigits,只要你想做
static func df2so(_ price: Double) -> String{
let numberFormatter = NumberFormatter()
numberFormatter.groupingSeparator = ","
numberFormatter.groupingSize = 3
numberFormatter.usesGroupingSeparator = true
numberFormatter.decimalSeparator = "."
numberFormatter.numberStyle = .decimal
numberFormatter.maximumFractionDigits = 2
return numberFormatter.string(from: price as NSNumber)!
}
我在 class 模型中创建它
然后当你打电话时,你可以接受另一个 class ,就像这样
print("InitData: result convert string " + Model.df2so(1008977.72))
//InitData: result convert string "1,008,977.72"
如何在 Swift 4:
let myDouble = 9999.99
let currencyFormatter = NumberFormatter()
currencyFormatter.usesGroupingSeparator = true
currencyFormatter.numberStyle = .currency
// localize to your grouping and decimal separator
currencyFormatter.locale = Locale.current
// We'll force unwrap with the !, if you've got defined data you may need more error checking
let priceString = currencyFormatter.string(from: NSNumber(value: myDouble))!
print(priceString) // Displays ,999.99 in the US locale
您可以为字符串或 Int 创建一个扩展,我将展示一个使用 String
的示例
extension String{
func toCurrencyFormat() -> String {
if let intValue = Int(self){
let numberFormatter = NumberFormatter()
numberFormatter.locale = Locale(identifier: "ig_NG")/* Using Nigeria's Naira here or you can use Locale.current to get current locale, please change to your locale, link below to get all locale identifier.*/
numberFormatter.numberStyle = NumberFormatter.Style.currency
return numberFormatter.string(from: NSNumber(value: intValue)) ?? ""
}
return ""
}
}
extension Float {
var localeCurrency: String {
let formatter = NumberFormatter()
formatter.numberStyle = .currency
formatter.locale = .current
return formatter.string(from: self as NSNumber)!
}
}
amount = 200.02
print("Amount Saved Value ",String(format:"%.2f", amountSaving. localeCurrency))
对我来说 return 0.00!
在我看来,访问它时 Extenstion Perfect return 0.00!为什么?
extension String{
func convertDoubleToCurrency() -> String{
let amount1 = Double(self)
let numberFormatter = NumberFormatter()
numberFormatter.numberStyle = .currency
numberFormatter.locale = Locale(identifier: "en_US")
return numberFormatter.string(from: NSNumber(value: amount1!))!
}
}
这是我一直在做的一个简单方法。
extension String {
func toCurrency(Amount: NSNumber) -> String {
var currencyFormatter = NumberFormatter()
currencyFormatter.usesGroupingSeparator = true
currencyFormatter.numberStyle = .currency
currencyFormatter.locale = Locale.current
return currencyFormatter.string(from: Amount)!
}
}
使用如下
let amountToCurrency = NSNumber(99.99)
String().toCurrency(Amount: amountToCurrency)
从 Swift 5.5 开始,您可以在 .formatted
:
的帮助下完成此操作
import Foundation
let amount = 12345678.9
print(amount.formatted(.currency(code: "USD")))
// prints: ,345,678.90
这应该支持最常见的货币代码,例如“EUR”、“GBP”或“CNY”。
同样,您可以将区域设置附加到 .currency
:
print(amount.formatted(
.currency(code:"EUR").locale(Locale(identifier: "fr-FR"))
))
// prints: 12 345 678,90 €
2022 年使用 Swift 5.5,我创建了扩展程序,使用您设备的区域设置或您作为参数传递的区域设置将 Float 或 Double 转换为货币。你可以在这里查看 https://github.com/ahenqs/SwiftExtensions/blob/main/Currency.playground/Contents.swift
import UIKit
extension NSNumber {
/// Converts an NSNumber into a formatted currency string, device's current Locale.
var currency: String {
return self.currency(for: Locale.current)
}
/// Converts an NSNumber into a formatted currency string, using Locale as a parameter.
func currency(for locale: Locale) -> String {
let numberFormatter = NumberFormatter()
numberFormatter.usesGroupingSeparator = locale.groupingSeparator != nil
numberFormatter.numberStyle = .currency
numberFormatter.locale = locale
return numberFormatter.string(from: self)!
}
}
extension Double {
/// Converts a Double into a formatted currency string, device's current Locale.
var currency: String {
return NSNumber(value: self).currency(for: Locale.current)
}
/// Converts a Double into a formatted currency string, using Locale as a parameter.
func currency(for locale: Locale) -> String {
return NSNumber(value: self).currency(for: locale)
}
}
extension Float {
/// Converts a Float into a formatted currency string, device's current Locale.
var currency: String {
return NSNumber(value: self).currency(for: Locale.current)
}
/// Converts a Float into a formatted currency string, using Locale as a parameter.
func currency(for locale: Locale) -> String {
return NSNumber(value: self).currency(for: locale)
}
}
let amount = 3927.75 // Can be either Double or Float, since we have both extensions.
let usLocale = Locale(identifier: "en-US") // US
let brLocale = Locale(identifier: "pt-BR") // Brazil
let frLocale = Locale(identifier: "fr-FR") // France
print("\(Locale.current.identifier) -> " + amount.currency) // default current device's Locale.
print("\(usLocale.identifier) -> " + amount.currency(for: usLocale))
print("\(brLocale.identifier) -> " + amount.currency(for: brLocale))
print("\(frLocale.identifier) -> " + amount.currency(for: frLocale))
// will print something like this:
// en_US -> ,927.75
// en-US -> ,927.75
// pt-BR -> R$ 3.927,75
// fr-FR -> 3 927,75 €
希望对您有所帮助,编码愉快!
我是 Swift 编程的新手,我一直在 Xcode 8.2 中创建一个简单的小费计算器应用程序,我在下面的 IBAction
中设置了我的计算。但是当我实际上 运行 我的应用程序并输入一个数量来计算(例如 23.45)时,它会出现超过 2 位小数。在这种情况下,如何将其格式化为 .currency
?
@IBAction func calculateButtonTapped(_ sender: Any) {
var tipPercentage: Double {
if tipAmountSegmentedControl.selectedSegmentIndex == 0 {
return 0.05
} else if tipAmountSegmentedControl.selectedSegmentIndex == 1 {
return 0.10
} else {
return 0.2
}
}
let billAmount: Double? = Double(userInputTextField.text!)
if let billAmount = billAmount {
let tipAmount = billAmount * tipPercentage
let totalBillAmount = billAmount + tipAmount
tipAmountLabel.text = "Tip Amount: $\(tipAmount)"
totalBillAmountLabel.text = "Total Bill Amount: $\(totalBillAmount)"
}
}
如果你想强制货币为 $,你可以使用这个字符串初始值设定项:
String(format: "Tip Amount: $%.02f", tipAmount)
如果你想让它完全依赖于设备的语言环境设置,你应该使用NumberFormatter
。这将考虑货币的小数位数以及正确定位货币符号。例如。双精度值 2.4 将 return es_ES 区域设置为“2,40 €”,jp_JP 区域设置为“¥ 2”。
let formatter = NumberFormatter()
formatter.locale = Locale.current // Change this to another locale if you want to force a specific locale, otherwise this is redundant as the current locale is the default already
formatter.numberStyle = .currency
if let formattedTipAmount = formatter.string(from: tipAmount as NSNumber) {
tipAmountLabel.text = "Tip Amount: \(formattedTipAmount)"
}
最好的方法是创建一个 NSNumberFormatter
。 (NumberFormatter
in Swift 3.)您可以请求货币,它会设置字符串以遵循用户的本地化设置,这很有用。
作为使用 NumberFormatter 的替代方法,如果您想强制使用美国格式的美元和美分字符串,您可以按以下方式格式化:
let amount: Double = 123.45
let amountString = String(format: "$%.02f", amount)
方法如下:
let currentLocale = Locale.current
let currencySymbol = currentLocale.currencySymbol
let outputString = "\(currencySymbol)\(String(format: "%.2f", totalBillAmount))"
第 1 行:您正在获取当前语言环境
第 2 行:您正在获取该语言环境的 currencySymbol。 ($、£ 等)
第 3 行:使用格式初始值设定项将 Double 截断为小数点后两位。
除了别人讨论的NumberFormatter
或者String(format:)
,你可以考虑使用Decimal
或者NSDecimalNumber
,自己控制四舍五入,避免浮动点问题。如果您正在做一个简单的小费计算器,那可能没有必要。但是,如果您要在一天结束时将小费相加,如果您不对数字进行四舍五入 and/or 使用十进制数进行计算,则可能会引入错误。
所以,继续配置格式化程序:
let formatter: NumberFormatter = {
let _formatter = NumberFormatter()
_formatter.numberStyle = .decimal
_formatter.minimumFractionDigits = 2
_formatter.maximumFractionDigits = 2
_formatter.generatesDecimalNumbers = true
return _formatter
}()
然后,使用十进制数:
let string = "2.03"
let tipRate = Decimal(sign: .plus, exponent: -3, significand: 125) // 12.5%
guard let billAmount = formatter.number(from: string) as? Decimal else { return }
let tip = (billAmount * tipRate).rounded(2)
guard let output = formatter.string(from: tip as NSDecimalNumber) else { return }
print("\(output)")
在哪里
extension Decimal {
/// Round `Decimal` number to certain number of decimal places.
///
/// - Parameters:
/// - scale: How many decimal places.
/// - roundingMode: How should number be rounded. Defaults to `.plain`.
/// - Returns: The new rounded number.
func rounded(_ scale: Int, roundingMode: RoundingMode = .plain) -> Decimal {
var value = self
var result: Decimal = 0
NSDecimalRound(&result, &value, scale, roundingMode)
return result
}
}
显然,您可以将上述所有“2 位小数”引用替换为适合您使用的货币的任何数字(或者可能使用小数位数的变量)。
你可以这样转换:这个函数转换为你保留 maximumFractionDigits,只要你想做
static func df2so(_ price: Double) -> String{
let numberFormatter = NumberFormatter()
numberFormatter.groupingSeparator = ","
numberFormatter.groupingSize = 3
numberFormatter.usesGroupingSeparator = true
numberFormatter.decimalSeparator = "."
numberFormatter.numberStyle = .decimal
numberFormatter.maximumFractionDigits = 2
return numberFormatter.string(from: price as NSNumber)!
}
我在 class 模型中创建它 然后当你打电话时,你可以接受另一个 class ,就像这样
print("InitData: result convert string " + Model.df2so(1008977.72))
//InitData: result convert string "1,008,977.72"
如何在 Swift 4:
let myDouble = 9999.99
let currencyFormatter = NumberFormatter()
currencyFormatter.usesGroupingSeparator = true
currencyFormatter.numberStyle = .currency
// localize to your grouping and decimal separator
currencyFormatter.locale = Locale.current
// We'll force unwrap with the !, if you've got defined data you may need more error checking
let priceString = currencyFormatter.string(from: NSNumber(value: myDouble))!
print(priceString) // Displays ,999.99 in the US locale
您可以为字符串或 Int 创建一个扩展,我将展示一个使用 String
的示例extension String{
func toCurrencyFormat() -> String {
if let intValue = Int(self){
let numberFormatter = NumberFormatter()
numberFormatter.locale = Locale(identifier: "ig_NG")/* Using Nigeria's Naira here or you can use Locale.current to get current locale, please change to your locale, link below to get all locale identifier.*/
numberFormatter.numberStyle = NumberFormatter.Style.currency
return numberFormatter.string(from: NSNumber(value: intValue)) ?? ""
}
return ""
}
}
extension Float {
var localeCurrency: String {
let formatter = NumberFormatter()
formatter.numberStyle = .currency
formatter.locale = .current
return formatter.string(from: self as NSNumber)!
}
}
amount = 200.02
print("Amount Saved Value ",String(format:"%.2f", amountSaving. localeCurrency))
对我来说 return 0.00! 在我看来,访问它时 Extenstion Perfect return 0.00!为什么?
extension String{
func convertDoubleToCurrency() -> String{
let amount1 = Double(self)
let numberFormatter = NumberFormatter()
numberFormatter.numberStyle = .currency
numberFormatter.locale = Locale(identifier: "en_US")
return numberFormatter.string(from: NSNumber(value: amount1!))!
}
}
这是我一直在做的一个简单方法。
extension String {
func toCurrency(Amount: NSNumber) -> String {
var currencyFormatter = NumberFormatter()
currencyFormatter.usesGroupingSeparator = true
currencyFormatter.numberStyle = .currency
currencyFormatter.locale = Locale.current
return currencyFormatter.string(from: Amount)!
}
}
使用如下
let amountToCurrency = NSNumber(99.99)
String().toCurrency(Amount: amountToCurrency)
从 Swift 5.5 开始,您可以在 .formatted
:
import Foundation
let amount = 12345678.9
print(amount.formatted(.currency(code: "USD")))
// prints: ,345,678.90
这应该支持最常见的货币代码,例如“EUR”、“GBP”或“CNY”。
同样,您可以将区域设置附加到 .currency
:
print(amount.formatted(
.currency(code:"EUR").locale(Locale(identifier: "fr-FR"))
))
// prints: 12 345 678,90 €
2022 年使用 Swift 5.5,我创建了扩展程序,使用您设备的区域设置或您作为参数传递的区域设置将 Float 或 Double 转换为货币。你可以在这里查看 https://github.com/ahenqs/SwiftExtensions/blob/main/Currency.playground/Contents.swift
import UIKit
extension NSNumber {
/// Converts an NSNumber into a formatted currency string, device's current Locale.
var currency: String {
return self.currency(for: Locale.current)
}
/// Converts an NSNumber into a formatted currency string, using Locale as a parameter.
func currency(for locale: Locale) -> String {
let numberFormatter = NumberFormatter()
numberFormatter.usesGroupingSeparator = locale.groupingSeparator != nil
numberFormatter.numberStyle = .currency
numberFormatter.locale = locale
return numberFormatter.string(from: self)!
}
}
extension Double {
/// Converts a Double into a formatted currency string, device's current Locale.
var currency: String {
return NSNumber(value: self).currency(for: Locale.current)
}
/// Converts a Double into a formatted currency string, using Locale as a parameter.
func currency(for locale: Locale) -> String {
return NSNumber(value: self).currency(for: locale)
}
}
extension Float {
/// Converts a Float into a formatted currency string, device's current Locale.
var currency: String {
return NSNumber(value: self).currency(for: Locale.current)
}
/// Converts a Float into a formatted currency string, using Locale as a parameter.
func currency(for locale: Locale) -> String {
return NSNumber(value: self).currency(for: locale)
}
}
let amount = 3927.75 // Can be either Double or Float, since we have both extensions.
let usLocale = Locale(identifier: "en-US") // US
let brLocale = Locale(identifier: "pt-BR") // Brazil
let frLocale = Locale(identifier: "fr-FR") // France
print("\(Locale.current.identifier) -> " + amount.currency) // default current device's Locale.
print("\(usLocale.identifier) -> " + amount.currency(for: usLocale))
print("\(brLocale.identifier) -> " + amount.currency(for: brLocale))
print("\(frLocale.identifier) -> " + amount.currency(for: frLocale))
// will print something like this:
// en_US -> ,927.75
// en-US -> ,927.75
// pt-BR -> R$ 3.927,75
// fr-FR -> 3 927,75 €
希望对您有所帮助,编码愉快!