Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/99.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 根据选定的货币代码格式化货币,而不考虑设备';s语言环境(Swift)_Ios_Swift_Locale_Currency_Numberformatter - Fatal编程技术网

Ios 根据选定的货币代码格式化货币,而不考虑设备';s语言环境(Swift)

Ios 根据选定的货币代码格式化货币,而不考虑设备';s语言环境(Swift),ios,swift,locale,currency,numberformatter,Ios,Swift,Locale,Currency,Numberformatter,我正在尝试根据用户选择的货币设置货币格式。如果未选择货币,则设备的当前区域设置用于格式化。但是,我有一些问题: 我正在使用数字格式化程序将double格式化为currency字符串 let formatter = NumberFormatter() formatter.numberStyle = .currency formatter.currencySymbol = "" if currencyCode != nil {

我正在尝试根据用户选择的货币设置货币格式。如果未选择货币,则设备的当前区域设置用于格式化。但是,我有一些问题:

我正在使用数字格式化程序将double格式化为currency字符串

let formatter = NumberFormatter()
    formatter.numberStyle = .currency
    formatter.currencySymbol = ""
        
    if currencyCode != nil {
        formatter.currencyCode = currencyCode
    }
        
    let amount = Double(amt/100) + Double(amt%100)/100
    return formatter.string(from: NSNumber(value: amount))
}
currencyCode基本上是用户选择的货币。但是,如果用户选择欧元,格式与美元几乎相同,这意味着它不考虑所选的货币。我知道我们不可能用currencyCode创建语言环境,因为EUR在26个不同的国家使用,所以不可能导出正确的语言环境

另外,由于我使用的是一种基本上填充小数位置的格式,然后是一、十分之一等等,而且一些货币不支持小数位置,例如PKR(巴基斯坦Ruppee),那么我如何满足这一要求呢

所以我的问题是,无论选择了哪个设备区域设置,如何正确格式化货币。 如果我的设备区域设置为USD,并且我创建了一个EUR列表,我希望列表中的所有付款都采用EUR格式。 因此,如果以美元计价,以欧元计价的价格为3403.23美元,则应为3403.23欧元。


关于如何设置格式有什么建议吗?谢谢

您可以动态地将
区域设置
与货币代码匹配,因为您可以从
区域设置
可用标识符
属性创建所有受支持的
区域设置
属性,然后您可以检查它们的
货币代码
属性以匹配用户输入的货币代码

extension Locale: CaseIterable {
    public static let allCases: [Locale] = availableIdentifiers.map(Locale.init(identifier:))
}

public extension Locale { 
    init?(currencyCode: String) { 
        guard let locale = Self.allCases.first(where: { $0.currencyCode == currencyCode }) else { return nil } 
        self = locale 
     } 
}

Locale(currencyCode: "EUR") // es_EA
Locale(currencyCode:"GBP") // kw_GB
但是,正如您所看到的,这可能会返回异国情调的区域设置,这可能不一定会提供所需的格式

我建议对应用程序支持的每个货币代码硬编码所需的
Locale
,这样您就可以100%确保格式始终符合您的要求。您也可以混合使用这两种方法,并对已知的货币代码使用硬编码的
Locale
s,但对更奇特的货币代码使用动态方法,您对它们的格式没有硬性要求。

简而言之 与货币相关的区域设置有两种:

  • 货币相关:这些与货币价值相关,仅取决于货币,在使用该货币的任何地方都有效。这只是国际ISO代码和小数位数,定义如下
  • 文化背景:这些取决于与用户的语言和国家相关的用法和实践,而不是直接与货币相关。通常,它是货币代码或符号相对于值的位置,以及小数点和千位分隔符
幸运的是,斯威夫特很好地发挥了作用。这里有一些代码,允许您调整与货币相关的设置,而无需涉及对用户非常重要的文化设置。我还将解释为什么不应该更改所有本地设置

代码 下面是演示代码,其中包含两种具有代表性的货币:

let value: Double = 1345.23
for mycur in ["USD", "TND", "EUR", "JPY" ] {
    let myformatter = NumberFormatter()
    myformatter.numberStyle = .currencyISOCode
    let newLocale = "\(Locale.current.identifier)@currency=\(mycur)" // this is it!
    myformatter.locale = Locale(identifier:newLocale)
    print ("currency:\(mycur): min:\(myformatter.minimumFractionDigits) max:\(myformatter.maximumFractionDigits)" 
    print ("result: \(myformatter.string(from: value as NSNumber) ?? "xxx")")
}
对于具有代表性的演示,我使用了:

  • 美元和欧元,与大多数货币一样,可以分为100个小单位(美分)
  • (Tunesian第纳尔),就像一手其他第纳尔货币一样,可以划分为1000个亚单位(毫)
  • 日元,在过去可以被划分为价值如此之小的子单位,以至于日本政府决定不再使用它们。这就是日元金额不再有小数的原因
结果 对于用户而言,将受益于,并查看小数点和千位分隔符以及他/她使用的定位

在我当前的语言环境中(在我的语言中,货币代码在右边,小数用逗号分隔,千用硬空格分隔),结果将是:

cur:USD: min:2 max:2 result: 1  345,23 USD
cur:TND: min:3 max:3 result: 1  345,230 TND
cur:EUR: min:2 max:2 result: 1  345,23 EUR
cur:JPY: min:0 max:0 result: 1  345 JPY
但如果你通常在讲英语的环境中工作,例如在美国文化中,你会得到:

cur:USD: min:2 max:2 result: USD 1,345.23
cur:TND: min:3 max:3 result: TND 1,345.230
cur:EUR: min:2 max:2 result: EUR 1,345.23
cur:JPY: min:0 max:0 result: JPY 1,345
工作原理: 代码的诀窍是创建一个新的区域设置,只需更改货币设置,但保留所有其他依赖于国家和语言的参数

    let newLocale = "\(Locale.current.identifier)@currency=\(mycur)" // this is it!
    myformatter.locale = Locale(identifier:newLocale)
为什么你不应该完全实现你想要的 如果您开始调整定位,以采用货币来源国的语言,您可能会激怒那些不再在预期位置看到货币代码的用户。幸运的是,这不会造成真正的混乱

示例:欧元是具有不同文化的国家的货币。因此,关于货币或货币符号定位的规则被定义为取决于金额出现的文本语言

现在,如果你开始采用另一种语言或国家,因为它是货币的母国,这将造成真正的混乱,尤其是对于较小的金额。此外,这并不总是可能的

例如:在加拿大,讲法语的加拿大人使用逗号小数分隔符书写相同的货币金额,而讲英语的加拿大人使用点小数分隔符书写相同的货币金额。这清楚地表明,决定使用分隔符的不是货币,而是用户的语言


因此,您应该尊重用户在这方面的设置,并且只调整特定于货币的设置。

有趣!这是一个不错的方法,但事实上,考虑到某些货币可能会返回多个地区,OP的方法应该重新考虑。这里最好的例子是CAD,默认格式取决于用户的语言(甚至不是国家)。因此,最好保持与语言相关的首选项不变。为什么不使用易出错的初始值设定项而不是静态met