如何将Double格式化为货币 - Swift 3

时间:2017-01-09 23:39:28

标签: ios swift formatting currency

我是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)"
    }
}

9 个答案:

答案 0 :(得分:61)

如果要强制货币为$:

,可以使用此字符串初始值设定项
String(format: "Tip Amount: $%.02f", tipAmount)

如果您希望它完全依赖于设备的区域设置,则应使用NumberFormatter。这将考虑货币的小数位数以及正确定位货币符号。例如。对于es_ES语言环境,double值2.4将返回“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)"
}

答案 1 :(得分:9)

执行此操作的最佳方法是创建NSNumberFormatter。 (Swift 3中的NumberFormatter。)您可以请求货币,它会设置字符串以遵循用户的本地化设置,这很有用。

如果你想强制使用美国格式的美元和美分字符串,你可以这样格式化:

let amount: Double = 123.45

let amountString = String(format: "$%.02f", amount)

答案 2 :(得分:9)

除了其他人讨论的NumberFormatterString(format:)之外,您可能还需要考虑使用DecimalNSDecimalNumber并自行控制舍入,从而避免出现浮点问题。如果你正在做一个简单的小费计算器,那可能就没有必要了。但是,如果您在一天结束时添加提示,如果您不对数字进行舍入和/或使用十进制数进行数学运算,则可能会引入错误。

因此,请继续配置格式化程序:

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小数位"任何数字的引用都适用于您正在使用的货币(或者可能使用变量作为小数位数)。

答案 3 :(得分:7)

如何在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 $9,999.99 in the US locale

答案 4 :(得分:6)

您可以为字符串或整数创建扩展名,我将使用字符串作为示例

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 ""
  }
}

link to get all locale identifier

答案 5 :(得分:4)

您可以这样转换:只要您愿意,此func转换为您的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)!
    } 

我在类Model中创建它 然后当你打电话时,你可以接受另一个类,比如这个

 print("InitData: result convert string " + Model.df2so(1008977.72))
//InitData: result convert string "1,008,977.72"

答案 6 :(得分:1)

 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!))!
    }
}

答案 7 :(得分:0)

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))

对我来说,它的回报是0.00! 对我来说,扩展性完美访问它时返回0.00!为什么?

答案 8 :(得分:-2)

以下是:

    let currentLocale = Locale.current
    let currencySymbol = currentLocale.currencySymbol
    let outputString = "\(currencySymbol)\(String(format: "%.2f", totalBillAmount))"

第一行:您正在获取当前区域设置

第二行:您正在获取该语言环境的currencySymbol。 ($,£等)

第3行:使用格式初始值设定项将Double到2的小数位截断。