2017-06-24 42 views
0

我有一個應用程序提供每30秒過期的數據(具體來說,h/m/s 11:30:00,11:30:30,11:31:00等) 。回合時間到最近的三十秒

我可以得到當前時間,但我不確定如何計算從現在到最近的三十秒之間的時間。

我發現的任何東西都在Objective-C中,我一直無法將其轉換。

這裏是我的嘗試:

func nearestThirtySeconds() -> Date? { 
     var components = NSCalendar.current.dateComponents([.second], from: self) 
     let second = components.second ?? 30 
     components.second = second >= 30 ? 60 - second : -second 
     return Calendar.current.date(byAdding: components, to: self) 
    } 

但這返回最接近的分鐘數(我想,它總是返回一個明確分鐘)

任何想法?

回答

0
let now = Date() 
var timeInterval = now.timeIntervalSinceReferenceDate 
timeInterval += 30 - timeInterval.truncatingRemainder(dividingBy: 30) 
let rounded = Date(timeIntervalSinceReferenceDate: timeInterval) 
print("\(now) rounded to nearest 30 seconds is \(rounded)") 
+0

您應該使用日曆計算。這可以打破一些奇怪的時區。 – Sulthan

+0

雖然這通常是真實的,如果你希望是準確的,在這裏你是明確的四捨五入時間和丟棄的準確性,所以我認爲這不重要,如果你是閏秒或其他什麼,但如果你關心,那麼您可以使用與DateComponents.second相同的數學方法。一般的公式是添加你想要的數字,然後減去除以該數字後的餘數。 –

+0

下面是一個「怪異」時區偏移量的示例:https://stackoverflow.com/a/44661976/1187415。所以這取決於你是否想要在本地時間或UTC時間四捨五入。 –

3

你能讓秒到30, 最接近的整數倍,然後添加圓角和原始 值的日期之間的區別:

extension Date { 
    func nearestThirtySeconds() -> Date { 
     let cal = Calendar.current 
     let seconds = cal.component(.second, from: self) 
     // Compute nearest multiple of 30: 
     let roundedSeconds = lrint(Double(seconds)/30) * 30 
     return cal.date(byAdding: .second, value: roundedSeconds - seconds, to: self)! 
    } 
} 

這應該是足夠好display rounded time,但它 不準確:A Date也包含小數秒,所以例如「11:30:10.123」的 將變爲「11:30:00」,而不是「11:30:00.000」 。這裏是一個解決了這個問題的另一種方法:

extension Date { 
    func nearestThirtySeconds() -> Date { 
     let cal = Calendar.current 
     let startOfMinute = cal.dateInterval(of: .minute, for: self)!.start 
     var seconds = self.timeIntervalSince(startOfMinute) 
     seconds = (seconds/30).rounded() * 30 
     return startOfMinute.addingTimeInterval(seconds) 
    } 
} 

現在seconds是因爲當前分鐘 (包括小數秒)的開始的時間間隔。該間隔四捨五入到最接近的 倍數爲30,並添加到分鐘的開頭。