在Swift中更改多种货币的分组分隔符、货币符号和位置。

3

我的应用程序使用多种货币,这些货币使用不同的格式,例如:

卢布的价格显示为:1,101 Руб.

美元相同金额的显示方式为:US $1 101

我该如何通过定义一组不同的格式来更改分组分隔符、货币符号和货币符号位置,以适应不同的货币。

以下是我的简短代码:

var formatter = NSNumberFormatter()
formatter.numberStyle = .CurrencyStyle
formatter.locale = NSLocale.currentLocale()
formatter.stringFromNumber(4500000)
//Output : $4,500,000.00
//Expected : 4,500,000 Руб.

1
作为一个三年的会员,你应该知道SO不是一个语言转换网站。你说你正在使用Swift,但我在你的帖子中看不到一行Swift代码。 - Leo Dabus
1
我无法更改分组分隔符、货币符号和货币符号位置。你不需要这样做,因为区域设置会为你处理。但是如果你确实需要这样做,你是否已经阅读了NSNumberFormatter文档?我没有看到你甚至尝试更改格式或货币代码。 - matt
你花了很多时间做什么?看看文档吧。你有两个选择:使用白俄罗斯的地区设置(阅读NSLocale的文档)或通过配置格式化器来指定货币符号、小数位数、分组符号等(阅读NSNumberFormatter的文档)。我强烈推荐前者。 - jcaron
@Aamir 尝试使用.locale = NSLocale(localeIdentifier:"be_BY"),它会给出 p.。 - Leo Dabus
1
"NSNumberFormatter在Swift中的文档不可用?这是个笑话吧?开发环境不是Swift而是Xcode,NSNumberFormatter在Xcode的文档中肯定是可用的。它也可以在线获取:https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSNumberFormatter_Class/" - jcaron
显示剩余3条评论
2个回答

23

Swift 4或更高版本

extension Formatter {
    static let belarusianRuble: NumberFormatter = {
        let formatter = NumberFormatter()
        // set the numberStyle to .CurrencyStyle
        formatter.numberStyle = .currency
        // set the desired negative and positive formats grouping, and currency symbol position
        formatter.positiveFormat = "#,##0 ¤"
        formatter.negativeFormat = "-#,##0 ¤"
        // set your custom currency symbol
        formatter.currencySymbol = "Руб"
        return formatter
    }()
}

let stringToDisplay = Formatter.belarusianRuble.string(for: 4500000)  // "4,500,000 Руб"

extension Formatter {
    static let currencyBYR: NumberFormatter = {
        let formatter = NumberFormatter()
        formatter.numberStyle = .currency
        formatter.positiveFormat = "#,##0 ¤"
        formatter.negativeFormat = "-#,##0 ¤"
        formatter.currencySymbol = "Руб"
        return formatter
    }()
    static let currencyEUR: NumberFormatter = {
        let formatter = NumberFormatter()
        formatter.locale = Locale(identifier: "pt_PT")
        formatter.numberStyle = .currency
        return formatter
    }()
    static let currencyUSD: NumberFormatter = {
        let formatter = NumberFormatter()
        formatter.locale = Locale(identifier: "en_US")
        formatter.numberStyle = .currency
        return formatter
    }()
    static let currencyBRL: NumberFormatter = {
        let formatter = NumberFormatter()
        formatter.locale = Locale(identifier: "pt_BR")
        formatter.numberStyle = .currency
        return formatter
    }()
    static let currencyRUB: NumberFormatter = {
        let formatter = NumberFormatter()
        formatter.locale = Locale(identifier: "ru_RU")
        formatter.numberStyle = .currency
        formatter.maximumFractionDigits = 0
        return formatter
    }()
    static let currencyLocale: NumberFormatter = {
        let formatter = NumberFormatter()
        formatter.locale = .current
        formatter.numberStyle = .currency
        return formatter
    }()
}

extension Numeric {
    var currencyLocale: String { return Formatter.currencyLocale.string(for: self) ?? "" }
    var currencyUSD: String { return Formatter.currencyUSD.string(for: self) ?? "" }
    var currencyEUR: String { return Formatter.currencyEUR.string(for: self) ?? "" }
    var currencyBYR: String { return Formatter.currencyBYR.string(for: self) ?? "" }
    var currencyBRL: String { return Formatter.currencyBRL.string(for: self) ?? "" }
    var currencyRUB: String { return Formatter.currencyRUB.string(for: self) ?? "" }
}

使用方法

let amount = 4500000.0

let stringLocale = amount.currencyLocale   // "$4,500,000.00"

let stringUSD = amount.currencyUSD         // "$4,500,000.00"
let stringEUR = amount.currencyEUR         // "4 500 000,00 €"
let stringBRL = amount.currencyBRL         // "R$ 4.500.000,00"
let stringBYR = amount.currencyBYR         // "4,500,000 Руб"
let stringRUB = amount.currencyRUB         // "4 500 000 ₽"

1
我最终得到了一个货币类,它使用当前区域设置的小数/千位分隔符和分组分隔符(感谢@jcaron在评论中的建议)。
该类提供了几个适合我的任务的自定义选项:
  • 货币符号
  • 最小/最大小数位数
  • 符号位置要么在左边要么在右边

class Currency {
    var formatter = NumberFormatter()
    var symbol: String
    var isRTL: Bool

    init(_ currencySymbol: String, minFractionDigits: Int, maxFractionDigits: Int, isRTL: Bool) {
        self.formatter.currencySymbol = ""
        self.formatter.minimumFractionDigits = minFractionDigits
        self.formatter.maximumFractionDigits = maxFractionDigits
        self.formatter.numberStyle = .currency

        self.symbol = currencySymbol
        self.isRTL = isRTL
    }

    func beautify(_ price: Double) -> String {
        let str = self.formatter.string(from: NSNumber(value: price))!
        if self.isRTL {
            return str + self.symbol
        }
        return self.symbol + str
    }
}

初始化必需的格式化程序

struct CurrencyFormatter {
    static let byr = Currency(" Руб.", minFractionDigits: 2, maxFractionDigits: 2, isRTL: true)
    static let usd = Currency("US $", minFractionDigits: 2, maxFractionDigits: 2, isRTL: false)
    static let rub = Currency("\u{20BD} ", minFractionDigits: 0, maxFractionDigits: 1, isRTL: false)
}

用法

CurrencyFormatter.byr.beautify(12345.67) // Output: 12 345,67 Руб.
CurrencyFormatter.usd.beautify(12345.67) // Output: US $12 345,67
CurrencyFormatter.rub.beautify(12345.67) // Output: ₽ 12 345,7

你应该使用结构体和静态变量来初始化你的数字格式化器,只需要初始化一次。你应该使用Double而不是Float。 - Leo Dabus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接