设置 MeasurementFormatter 实例的语言环境会使实例上设置的任何 numberFormatter 属性 选项无效

Setting a locale of MeasurementFormatter instance voids any numberFormatter property options set on the instance

已解决 多亏了 Martin R,这已经通过必须先设置 locale 来解决。所以:

import Foundation
let formatter = MeasurementFormatter()
formatter.locale = Locale(identifier: "en_GB") // Set locale first
formatter.numberFormatter.minimumFractionDigits = 4 // Now set numberFormatter properties
formatter.numberFormatter.maximumFractionDigits = 4
let distanceInKm = 16.093 // ~10 mi
var measurement: Measurement<UnitLength> = Measurement(value: distanceInKm, unit: .kilometers)
let string = formatter.string(from: measurement) // 9.998 mi
assert(string == "9.9998 mi") // Passes

===================================

经过几个小时的困惑后,我发现在 MeasurementFormatter 实例上设置区域设置会使同时在其上设置的任何 numberFormatter 设置无效。

例如: 1. 运行 这个:

import Foundation
let formatter = MeasurementFormatter()
formatter.numberFormatter.minimumFractionDigits = 4
formatter.numberFormatter.maximumFractionDigits = 4
let distanceInKm = 16.093 // ~10 mi
var measurement: Measurement<UnitLength> = Measurement(value: distanceInKm, unit: .kilometers)
let string = formatter.string(from: measurement) // 9.998 mi
assert(string == "9.9998 mi") // Passes
  1. 现在向 MeasurementFormatter 实例添加一个区域设置并从相同的距离创建一个字符串
formatter.locale = Locale(identifier: "en_GB") // Set the locale
let string2 = formatter.string(from: measurement) // 10 mi
assert(string2 == "9.9998 mi") // FAILS: No longer formatted to 4 fractional digits

我希望在第二种情况下断言仍然有效,得到一个格式化为 numberFormatter 属性 设置的小数点后 4 位的字符串。相反,它似乎被忽略了。

我尝试在设置语言环境后再次设置 numberFormatter 属性,但这并没有改变任何东西,例如,

formatter.locale = Locale(identifier: "en_GB") // Set the locale
formatter.numberFormatter.minimumFractionDigits = 4 // set numberFormatter properties again
formatter.numberFormatter.maximumFractionDigits = 4
let string3 = formatter.string(from: measurement) // still 10 mi
assert(string3 == "9.9998 mi") // FAILS: Still not formatted as per numberFormatter options

我找不到关于 SO 的报告,我想我会把它放在这里,这样其他人就可以找到它而不是浪费时间。我用 apple 打开了一个雷达(并注意到其他人在 2017 年的时间单位做了一个类似的!!!)。我仍然希望我遗漏了一些东西,and/or 如果有人对如何使用区域设置格式化数字有任何建议(在我的实际来源中,我实际上是在根据用户的区域设置使用公制和英制距离) ,将不胜感激。

使用自定义语言环境 MeasurementFormatter 的唯一可靠方法似乎是:

  • 创建一个新的格式化程序,
  • 先赋值formatter.locale
  • 然后分配其他属性,例如所需的小数位数,
  • 使用新的格式化程序。

Technical Q&A QA1480 中提到了 (NS)DateFormatter 的类似行为:

... you should first set the locale of the date formatter ...

示例:

let formatter = MeasurementFormatter()
formatter.locale = Locale(identifier: "de_DE")
formatter.numberFormatter.minimumFractionDigits = 4
formatter.numberFormatter.maximumFractionDigits = 4

let distanceInKm = 16.093
let measurement = Measurement(value: distanceInKm, unit: UnitLength.kilometers)
let string = formatter.string(from: measurement)

print(string) // 16,0930 km