Установка языкового стандарта для экземпляра MeasurementFormatter аннулирует любые параметры свойства numberFormatter, установленные для этого экземпляра - PullRequest
1 голос
/ 15 марта 2019

решаемые Благодаря 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

Я ожидаю, что во втором случае утверждение все еще будет работать, получая строку, отформатированную до 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 году !!!). Я все еще надеюсь, что что-то упустил, и / или если у кого-то есть какие-либо предложения о том, как по-прежнему форматировать число, используя локаль (в моем реальном источнике я фактически работаю с метрическими и имперскими расстояниями, основанными на локали пользователя), что будет высоко ценится.

1 Ответ

1 голос
/ 15 марта 2019

Единственный надежный способ использования MeasurementFormatter с пользовательской локалью:

  • Создайте новый форматер,
  • назначьте formatter.locale сначала,
  • затем назначьте другие свойства, такие как желаемое количество цифр дроби,
  • используйте новый форматер.

Аналогичное поведение упоминается в Технические вопросы и ответы 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
...