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

Posted

技术标签:

【中文标题】设置 MeasurementFormatter 实例的语言环境会使该实例上设置的任何 numberFormatter 属性选项无效【英文标题】:Setting a locale of MeasurementFormatter instance voids any numberFormatter property options set on the instance 【发布时间】:2019-03-15 10:05:54 【问题描述】:

已解决 感谢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
    现在向 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

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

我尝试在设置语言环境后再次设置 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 的报道,我想我会把它放在这里以便其他人可以找到它,而不是浪费时间。我用苹果打开了一个雷达(并注意到其他人在 2017 年的单位时间内做了类似的雷达!!!)。我仍然希望我遗漏了一些东西,和/或如果有人对如何使用语言环境格式化数字有任何建议(在我的实际来源中,我实际上是根据用户的语言环境使用公制和英制距离),那将不胜感激。

【问题讨论】:

看来您必须先分配formatter.locale,然后再设置任何其他属性。 我试过了(见最后一个代码块),没有变化? 唯一可靠的方法似乎是:创建一个新的格式化程序,分配区域设置,然后是其他属性。 – 一个(远程)相关的行为在此处“记录”developer.apple.com/library/archive/qa/qa1480/_index.html 用于 NSDateFormatter:“您应该首先设置日期格式化程序的区域设置” 如果您在初始化后直接设置语言环境,然后再设置numberFormatter 属性,它就可以正常工作。 let formatter = MeasurementFormatter() ; formatter.locale = Locale(identifier: "en_GB") // Set the locale ; formatter.numberFormatter.minimumFractionDigits = 4; formatter.numberFormatter.maximumFractionDigits = 4 产生预期的结果。 如果您分配 不同的 语言环境,您的最后一个代码块实际上可以工作... 【参考方案1】:

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

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

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

...您应该首先设置日期格式化程序的语言环境...

例子:

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

【讨论】:

以上是关于设置 MeasurementFormatter 实例的语言环境会使该实例上设置的任何 numberFormatter 属性选项无效的主要内容,如果未能解决你的问题,请参考以下文章

如何在 x86 实模式下正确设置 SS、BP 和 SP?

#私藏项目实操分享#SCCM实用功能-基线设置之检查补丁是否安装

2-6 Flutter开发环境与Android开发环境设置实操(Windows)

#私藏项目实操分享#SCCM实用功能-基线设置之黑名单软件检查

打造网络营销利器-第1篇-TDK设置实操-网站优化进阶

RENIX软件V6板卡速率设置——网络测试仪实操