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 Я получил плоские неправильные значения для некоторых компонентов даты, где это не было проблемой округления. Смотрите мой вопрос по этой ссылке: