NSDateComponentsFormatter исключает единицы. Зачем?

Я пытаюсь использовать NSDateComponentsFormatter генерировать читаемые пользователем строки длительностей. Хотя в целом это работает довольно хорошо, иногда результаты странные (или просто неверные):

// 22d 23h 15m 34.123s
let timeInterval: NSTimeInterval = 34.123 + 60.0 * (15.0 + 60.0 * (23.0 + 24.0 * 22.0))

let formatter = NSDateComponentsFormatter()
formatter.allowedUnits = [NSCalendarUnit.Year, NSCalendarUnit.Day, NSCalendarUnit.Hour, NSCalendarUnit.Minute, NSCalendarUnit.Second]
formatter.maximumUnitCount = 2
formatter.unitsStyle = .Abbreviated
formatter.zeroFormattingBehavior = .Default

// expected result:     22d 23h
// actual result:       23d 16m
let result = formatter.stringFromTimeInterval(timeInterval)

Он не только пропускает поле часов в этом примере, но также округляет дни и минуты. Я бы предположил, что после округления дней он должен "использовать" оставшиеся минуты в округлении. Исходя из этого, пользователь будет думать, что продолжительность определенно превышает 23 дня, а на самом деле это не так.

2 ответа

Учтите, что 27 марта 2016 года летнее время меняется во многих странах.

Абсолютный временной интервал может не совпадать с календарным расчетом на основе календарных единиц.

По возможности избегайте математику даты с буквенными числами.

От NSDateComponentsFormatter документация относительно его calendar имущество

Средство форматирования использует календарь в этом свойстве для форматирования значений, которые не имеют собственного собственного календаря. Например, средство форматирования использует этот календарь при форматировании значения NSTimeInterval.

Обновить:

Смотрите также этот пример, он создает дату 27 марта 2016 года, добавляет добавление одного дня через компоненты даты и вычисляет интервал

let calendar = NSCalendar.currentCalendar()
let startDate = calendar.dateWithEra(1, year: 2016, month: 3, day: 27, hour: 0, minute: 0, second: 0, nanosecond: 0)!
let endDate = calendar.dateByAddingUnit(.Day, value: 1, toDate: startDate, options: [])!

let formatter = NSDateComponentsFormatter()
formatter.allowedUnits = [.Hour, .Minute, .Second]
formatter.unitsStyle = .Abbreviated

let result = formatter.stringFromDate(startDate, toDate: endDate)
print(result) // 23h

На основании проведенного ограниченного тестирования NSDateComponentsFormatter содержит ошибки в версиях iOS

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

Смотрите мой вопрос по этой ссылке:

Получение результатов от NSDateComponentsFormatter

Другие вопросы по тегам