2016-03-04 139 views
1

我正在嘗試使用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

基於我做的有限測試,NSDateComponentsFormatter在iOS版本< iOS 9和Mac OS < 10.11中有問題。

我得到了一些日期組件的錯誤值,它不是一個舍入問題。

見我的問題在此鏈接:

Getting screwy results from NSDateComponentsFormatter

+0

這是不幸的...和我使用OS X 10.11和iOS 9,但我仍然遇到這個問題。 –

+1

有時NSDateComponentsFormatter將顯示比maximumUnitCount更多的值。請參閱https://openradar.appspot.com/26354907。仍然發生在iOS 10中。非常令人失望。 – phatmann

4

認爲,關於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 
+0

在實際代碼中,timeInterval當然是使用適當的日曆日期進行計算的。爲了簡潔起見,我只是把它留在這裏。 *編輯:*並設置正確的日曆。 –

+0

查看可能已更新的答案。 – vadian

+0

這仍然可能是正確的選擇,@vadian。顯然,'NSDateComponentsFormatter'解釋了相對於當前日期和時間的時間間隔(據我所知,這是沒有記錄的)。也沒有辦法改變它的'錨'日期。因此,在我看來,當您接近夏令時開關時,結果可能會關閉一個小時。 –