【问题标题】:Can Locale identify country by currency code?Locale 可以通过货币代码识别国家吗?
【发布时间】:2019-05-04 09:36:48
【问题描述】:

我在此处以及官方文档中寻找答案,但我找不到答案。我有货币代码(例如“EUR”)。我需要获取国家代码(例如“欧盟”)。所以我看到我可以反过来做(通过使用国家代码获取货币代码),但我试图根据我的需要改变这个解决方案,结果我得到了 nil 。我也知道我可以使用简单的解决方案 - 从货币代码中删除最后一个字母以获取国家代码(它适用于我的 API 数据中的大多数情况,但并非无处不在) - 但我觉得这种方法不安全。所以我的问题就像标题一样:我可以使用语言环境从货币代码中识别国家吗?

这是我的方法:

使用 NSLocale

extension NSLocale {

   static func currencySymbolFromCode(code: String) -> String? {
      let localeIdentifier = NSLocale.localeIdentifier(fromComponents: [NSLocale.Key.currencyCode.rawValue : code])
      let locale = NSLocale(localeIdentifier: localeIdentifier)
      return locale.object(forKey: NSLocale.Key.countryCode) as? String
}

}

使用区域设置

extension Locale {    
  static let countryCode: [String: String] = Locale.isoCurrencyCodes.reduce(into: [:]) {
        let locale = Locale(identifier: Locale.identifier(fromComponents: [NSLocale.Key.currencyCode.rawValue: $1]))
        $0[$1] = (locale.regionCode)
    }
}

【问题讨论】:

  • 这应该如何工作?例如,欧元 (EUR) 是 19 个不同国家的货币。美元 (USD) 也是多个国家/地区的货币。
  • “欧盟”不是国家/地区。
  • 是的,这是正确的。也许我会多解释一下我想要实现的目标。我想获得给定货币的标志 - 例如如果您在欧盟中使用 unicode,那么您将获得欧盟旗帜。而且我需要每种货币的标志(或者如果没有,则返回空字符串或零)。我有获取给定区域代码的这个标志的代码,但我必须从货币代码中获取该区域代码
  • 我所做的,可能也是大多数显示货币标志的应用程序的做法,就是在货币代码之后命名货币图像。简单的。无需尝试将货币代码映射到其他任何内容。有“EUR”货币代码吗?然后加载一个名为“EUR.png”的图像。拥有“USD”,然后加载“USD.png”。

标签: ios swift locale


【解决方案1】:

一个货币可以关联多个国家,你应该创建自己的自定义数据实现,比如下面的json

{
"EUR":"PL",
"USD":"CA"
}

在您的 Xcode 项目中创建一个文件,并将其命名为例如data.json,然后像上面这样粘贴JSON,最后使用下面的方法

func getCountryCode(currency: String) -> String? {
    var countryCode: String?
    let url = Bundle.main.url(forResource: "data", withExtension: "json")!
    do {
        let data = try Data(contentsOf: url)
        let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: String]
        countryCode = json?[currency]
    } catch {
        print(error.localizedDescription)
    }

    return countryCode
}

用法

if let countryCode = getCountryCode(currency: "EUR") {
    print(countryCode)
}

【讨论】:

  • 我想过这种方法,这是正确的,但我希望我可以在没有额外文件(如这个 json)的情况下做到这一点,在我看来这将是更简单和优雅的方式。但也许这是不可能的,这将是最好的解决方案。
【解决方案2】:

@AamirR 的回答有点不准确。

  • EUR != PL, PL = PLN = 波兰
  • USD != CA, CA = CAD = 加拿大

在大多数情况下(有一些例外),货币代码的前 2 个字母 = ISO 3166-2 国家代码:

  • PLN = PL = 波兰
  • GBP = GB = 英国
  • USD = US = 美国
  • AMD = AM = 亚美尼亚
  • CZK = CZ = 捷克共和国
  • BRL = BR = 巴西利亚

等等……

因此,如果您有货币代码,您可以获得国家名称(准确率为 99%),如下所示:

let currencyCode = "USD"
let countryCode = String(currencyCode.prefix(2))
let countryName = Locale.current.localizedString(forRegionCode: countryCode)
        
print(countryName)

Optional("United States")

但是,正如上面的一些评论,例如欧盟不是一个国家,看起来在您的特定情况下您不需要国家标志,您需要“货币标志”,因此对于欧元,您将显示欧盟标志,这是正确的,因为您无法确定要显示哪个欧盟国家标志 - 法国、德国等......所以这种方法可能适用于将货币映射到国家标志。

虽然有一些例外,就货币代码的前 2 个字母与国家名称的前 2 个字母不匹配而言,从 ISO 3166-2 国家代码的角度来看,它们仍然匹配:

  • CHF = CH = 瑞士
  • HRK = HR = 克罗地亚
  • DKK = DK = 丹麦

...等等

另一个有趣的模式是货币代码的前 2 个字母,通常与国家互联网域匹配,但同样也有一些例外。

【讨论】:

    猜你喜欢
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-10
    • 1970-01-01
    • 1970-01-01
    • 2010-09-19
    • 2017-04-09
    相关资源
    最近更新 更多