DateComponentsFormatter не работает с датами в далеком прошлом

Я использую встроенный DateComponentsFormatter, чтобы выяснить количество лет между текущим днем ​​и другой датой. Если дата уходит слишком далеко в прошлом, например, 1940 г., возвращаемые единицы неверны:

let dateComponents = DateComponents(year: 1940, month: 1, day: 2, hour: 1, minute: 1, second: 1)

let date = Calendar.current.date(from: dateComponents)!

let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.allowedUnits = [.year]
dateComponentsFormatter.unitsStyle = .full

print(dateComponentsFormatter.string(from: abs(date.timeIntervalSinceNow)))

Это печатает -58 years что неверно. Это ошибка Apple? Я делаю что-то неправильно?

1 ответ

Решение

Это ошибка в DateComponentsFormatterРеализация. Очевидно, они используют Int32 для представления временных интервалов.

Я столкнулся с той же проблемой, очень легко воспроизвести:

let interval: TimeInterval = ... some number here
let formatter = DateComponentsFormatter()
formatter.allowedUnits = [.second]
formatter.unitsStyle = .abbreviated
print(formatter.string(from: interval) ?? "")

Предполагается, что это будет выводить только количество секунд без каких-либо специальных вычислений. Даже это работает только, как ожидалось, до 2147483647 (что, случается, Int32.max). Все это просто переполняется и приводит к неверным результатам.

Это максимальное "поддерживаемое" количество секунд составляет 68y 2w 4d 3h 14m 7s, что объясняет, почему вы видите это также.

UPD

Кто-то уже подал радар: http://www.openradar.me/32513237 и упомянул обходной путь, и он работает!

В вашем случае это было бы вместо использования:

let date = Calendar.current.date(from: dateComponents)!
let now = Date()
dateComponentsFormatter.string(from: date, to: now)
Другие вопросы по тегам