Может ли DateComponentsFormatter форматировать дробные секунды?

Я хочу напечатать, например, значение 1,5 как «1,5 секунды», как это делает временная шкала Safari, и я пытаюсь использовать для этого DateComponentsFormatter.

К сожалению, его .allowedUnits сводится только к .second (хотя в перечислении есть .nanosecond). Я попытался установить .allowsFractionalUnits = true, но все равно получаю "0 сек".

Есть ли способ получить дробные секунды из DateComponentsFormatter?


person Ssswift    schedule 08.04.2017    source источник
comment
Какой метод вы используете для форматирования чего?   -  person Willeke    schedule 09.04.2017
comment
Виллеке: Единственный метод, который принимает параметр 1.5: string(from:​ Time​Interval).   -  person Ssswift    schedule 09.04.2017
comment
Интервал времени внутренне транслируется в NSDateComponents.   -  person Willeke    schedule 10.04.2017
comment
Виллеке: Да, я так и предполагал. Это логичный способ их реализации. Так?   -  person Ssswift    schedule 10.04.2017
comment
Вы нашли способ получить 1,5 секунды от DateComponentsFormatter? Не может быть, чтобы Apple забыла это реализовать.   -  person Daniel    schedule 20.06.2019
comment
@Daniel К сожалению, это похоже на правду, начиная с iOS 13.3. Я не нашел способа получить локализованный вывод за 1,5 секунды из DateComponentsFormatter. Выдает только 1,5. Супер раздражает.   -  person Womble    schedule 10.03.2020


Ответы (1)


Для стиля позиционных единиц DateComponentsFormatter можно использовать вместе с NumberFormatter для получения строки с учетом локали.

func format(_ seconds: TimeInterval) -> String {
  let components = DateComponentsFormatter()
  components.allowedUnits = [.minute, .second]
  components.allowsFractionalUnits = true // does not work as expected
  components.unitsStyle = .positional
  components.zeroFormattingBehavior = .pad

  let fraction = NumberFormatter()
  fraction.maximumIntegerDigits = 0
  fraction.minimumFractionDigits = 0
  fraction.maximumFractionDigits = 3
  fraction.alwaysShowsDecimalSeparator = false

  let fractionalPart = NSNumber(value: seconds.truncatingRemainder(dividingBy: 1))

  return components.string(from: seconds)! + fraction.string(from: fractionalPart)!
}

print(Locale.current) // ru_RU (current)
print(format(600.5))  // 10:00,5 <- note locale specific decimal separator

К сожалению, использование этого метода для других стилей даты еще более хакерское.

person nikstar    schedule 02.03.2020