如何根据十进制值格式化货币?

时间:2015-05-16 02:50:27

标签: ios swift

我正在使用NSDecimalNumber格式化货币,并希望获得以下输入和输出:

9.99 --> 9.99 10 --> 10 10.00 --> 10 9.90 --> 9.90 9.9 --> 9.90 0 --> 0 0.01 --> 0.01 20 --> 20 10.01 --> 10.01

我如何在Swift中执行此操作。

编辑:基本上如果有美分(即美分> 0)则显示美分。否则,不要。

6 个答案:

答案 0 :(得分:6)

您的规则是"如果其中任何一个非零,则显示两个小数位;否则,不显示小数位数,也不显示小数点“。我会以最直接的方式做到这一点:

let number = NSDecimalNumber(string: "12345.00")
let formatter = NSNumberFormatter()
formatter.positiveFormat = "0.00"
let formattedString = formatter.stringFromNumber(number)!
    .stringByReplacingOccurrencesOfString(".00", withString: "")

答案 1 :(得分:3)

您可以使用NSNumberFormatter的货币格式。但是,似乎没有一种内置的方法可以按照你想要的方式进行四舍五入。这是一个解决方法:

let formatter = NSNumberFormatter()
formatter.numberStyle = NSNumberFormatterStyle.CurrencyStyle

func numToCurrency (num: Double) -> String {
    if floor(num) == num {
        formatter.minimumFractionDigits = 0
        formatter.maximumFractionDigits = 0
    }
    else {
        formatter.minimumFractionDigits = 2
        formatter.maximumFractionDigits = 2
    }
    return formatter.stringFromNumber(num)!
}

numToCurrency(9)    // "$9"
numToCurrency(9.9)  // "$9.90"

检查NSNumberFormatter class reference以获取更多配置选项(您可能需要为此格式化程序设置区域设置以自动为当前用户使用正确的国际货币符号。)

答案 2 :(得分:1)

编辑/更新:Xcode 8.3•Swift 3.1

extension Formatter {
    static let noFractionDigits: NumberFormatter = {
        let formatter = NumberFormatter()
        formatter.minimumFractionDigits = 0
        formatter.maximumFractionDigits = 0
        formatter.minimumIntegerDigits = 1
        return formatter
    }()
    static let twoFractionDigits: NumberFormatter = {
        let formatter = NumberFormatter()
        formatter.minimumFractionDigits = 2
        formatter.maximumFractionDigits = 2
        formatter.minimumIntegerDigits = 1
        return formatter
    }()
}

extension FloatingPoint {
    var customDescription: String {
        return rounded(.down) == self ?
        Formatter.noFractionDigits.string(for: self) ?? "" :
        Formatter.twoFractionDigits.string(for: self) ?? ""
    }
}

extension String {
    var double: Double { return Double(self) ?? 0 }
}
let array = ["9.99","10","10.00","9.90","9.9"]
let results = array.map { $0.double.customDescription }
results    // ["9.99", "10", "10", "9.90", "9.90"]

答案 3 :(得分:1)

(在这里回答,因为一个封闭的问题被重新引导到这个......)

也许最简单的路线,特别是因为它标记为“Swift”,是确定它是否是一个整数:

if value.truncatingRemainder(dividingBy: 1) == 0 {
    // it's a whole number,
    // so format WITHOUT decimal places, e.g. $12
} else {
    // it's a fraction,
    // so format WITH decimal places, e.g. $12.25
}

额外的好处是避免使用区域设置和货币格式的问题...当您在德国时,不会搜索/替换“.00”,例如,格式为“,00”

答案 4 :(得分:0)

以下是如何创建自定义格式化程序类来为您处理此问题:

import Foundation

class CustomFormatter: NSNumberFormatter {
  required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
  }

  override init() {
    super.init()
    self.locale = NSLocale.currentLocale()
    self.numberStyle = .DecimalStyle
  }

  func isIntegerNumber(number:NSNumber) -> Bool {
    var value: NSDecimal = number.decimalValue
    if NSDecimalIsNotANumber(&value) { return false }
    var rounded = NSDecimal()
    NSDecimalRound(&rounded, &value, 0, NSRoundingMode.RoundPlain)
    return NSDecimalCompare(&rounded, &value) == NSComparisonResult.OrderedSame
  }

  override func stringFromNumber(number: NSNumber) -> String? {
    if isIntegerNumber(number)  {
      self.minimumFractionDigits = 0
      self.maximumFractionDigits = 0
      return super.stringFromNumber(number)
    }
    else {
      self.minimumFractionDigits = 2
      self.maximumFractionDigits = 2
      return super.stringFromNumber(number)
    }
  }
}

let formatter = CustomFormatter()
formatter.stringFromNumber(NSDecimalNumber(double: 5.00)) // -> "5"
formatter.stringFromNumber(NSDecimalNumber(double: 5.01)) // -> "5.01"
formatter.stringFromNumber(NSDecimalNumber(double: 5.10)) // -> "5.10"

感谢this post正确测试NSDecimal是否为整数的方法。

答案 5 :(得分:0)

我认为最好让currencyStyle确定maximumFractionDigits。只需将minimumFractionDigits设置为0即可。代码稍微短一些,但如果你设置了语言环境作为奖励,这种方式将允许没有2位小数的语言。

使用NSNumberFormatter为您提供货币符号,小数位和逗号的好处,所有这些都在不同语言环境的完美位置。

extension NSNumber {
    func currencyString()  -> String? {
        let formatter = NSNumberFormatter()
        formatter.numberStyle = .CurrencyStyle
        if self.isEqualToNumber(self.integerValue) {
            formatter.minimumFractionDigits = 0
        }
        return formatter.stringFromNumber(self)
    }
}

let inputArray: [NSDecimalNumber] = [9.99, 10, 10.00, 9.90, 0, 0.01, 20, 10.01, 0.5, 0.055, 5.0]
let outputArray: [String] = inputArray.map({return $0.currencyString() ?? "nil"})
print(outputArray)

["$9.99", "$10", "$10", "$9.90", "$0", "$0.01", "$20", "$10.01", "$0.50", "$0.06", "$5"]

向NSNumberFormatter添加区域设置如下所示(例如,来自SKProduct对象):

formatter.locale = product!.priceLocale

对于OSX应用,您需要添加:

formatter.formatterBehavior = .Behavior10_4