NSDateComponentsFormatter

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)

它不仅省去了本例中的hours字段,而且还对days和minutes进行了取整。我想,一旦这些天都凑齐了,就应该把剩下的几分钟都“用光”。从结果来看,用户会认为持续时间肯定超过23天,而实际上并非如此。

最佳答案

考虑到2016年3月27日许多国家的夏令时变化。
绝对时间间隔可能与基于日历单位的日历计算不同。
尽可能避免使用文字数字进行日期计算。
从关于其NSDateComponentsFormatter属性的calendar文档
格式化程序使用此属性中的日历来格式化没有自己固有日历的值。例如,格式化程序在格式化nstimeInterval值时使用此日历。
更新:
另请参见此示例,它创建一个日期2016年3月27日,通过日期组件添加一天并计算间隔

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

10-08 14:23