2014-10-28 54 views
57

我正在寫一段代碼,我想要時間按住按鈕多長時間。要做到這一點,我在按下按鈕時記錄了一個NSDate(),並且在釋放按鈕時嘗試使用timeIntervalSinceDate函數。這似乎工作,但我找不到任何方式來打印結果或切換到一個整數。使用Swift查找NSDates之間的秒數差異作爲整數使用Swift

var timeAtPress = NSDate() 

@IBAction func pressed(sender: AnyObject) { 
    println("pressed") 
    timeAtPress = NSDate() 
} 

@IBAction func released(sender: AnyObject) { 
    println("released") 
    var elapsedTime = NSDate.timeIntervalSinceDate(timeAtPress) 
    duration = ??? 
} 

我見過一些類似的問題,但我不知道C因此我很難理解給出的答案。如果有更有效的方法來查明按鈕被按下多久,我願意接受建議。提前致謝。

回答

118

您嘗試計算elapsedTime不正確。在斯威夫特3,這將是:

let elapsed = Date().timeIntervalSince(timeAtPress) 

注意()Date引用後。 Date()實例化一個新的日期對象,然後timeIntervalSince返回該與timeAtPress之間的時間差。這將返回一個浮點值(技術上,一個TimeInterval)。

如果你想,作爲截斷爲Int值,你可以用:

let duration = Int(elapsed) 

而且,順便說一句,你的timeAtPress變量的定義並不需要實例化一個Date對象。我相信你想要的結果:

var timeAtPress: Date! 

定義變量作爲Date變量(隱式解開一個),但你可能推遲該變量的實際實例,直到pressed被調用。


另外,我經常使用CFAbsoluteTimeGetCurrent(),例如,

var start: CFAbsoluteTime! 

而當我想設置startTime,我做了以下內容:

start = CFAbsoluteTimeGetCurrent() 

當我要計算的經過的秒數,我執行以下操作:

let elapsed = CFAbsoluteTimeGetCurrent() - start 

值得一提的是,CFAbsoluteTimeGetCurrent文件警告我們:

這個功能千呼萬喚不保證單調遞增的結果。系統時間可能由於與外部時間參考同步或由於明確的時鐘用戶更改而降低。

這意味着,如果您不幸測量到其中一個調整發生時的經過時間,最終可能會計算不正確的經過時間。這也適用於NSDate/Date計算。這是最安全的使用mach_absolute_time基於計算(與CACurrentMediaTime最容易做到):

let start = CACurrentMediaTime() 

let elapsed = CACurrentMediaTime() - start 

這使用mach_absolute_time,但避免了一些在Technical Q&A QA1398概述複雜性。

但請記住,當設備重新啓動時,CACurrentMediaTime/mach_absolute_time將被重置。因此,如果您需要在應用程序運行時計算準確的經過時間,請使用CACurrentMediaTime。但是,如果您要將此開始時間保存在永久性存儲中,您可能還記得應用程序在未來某個日期重新啓動的時間,那麼您必須使用DateCFAbsoluteTimeGetCurrent,並且可能存在任何可能不準確的情況。

+3

哇,謝謝來搶!你的回答非常有幫助並且易於理解。我非常感謝關於CFAbsoluteTime的提示。我一定會用它! – Erik 2014-10-31 21:52:05

+0

timeIntervalSinceDate的維度是什麼? – eugene 2015-11-10 10:55:52

+1

它返回['NSTimeInterval'](https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Miscellaneous/Foundation_DataTypes/index.html#//apple_ref/c/tdef/NSTimeInterval) ,它以秒數來衡量。 – Rob 2015-11-10 14:23:32

19

NSDate()和NSCalendar()聲音是一個不錯的選擇。使用日曆計算並將實際的數學部分留給框架。以下是獲得兩個NSDate()夫特秒之間2時間之間

let startDate = NSDate() 
let endDate = NSDate() 
let calendar = NSCalendar.currentCalendar() 
let dateComponents = calendar.components(NSCalendarUnit.CalendarUnitSecond, fromDate: startDate, toDate: endDate, options: nil) 
let seconds = dateComponents.second 
println("Seconds: \(seconds)") 
-5

對於3 秒的一個簡單的例子 「HH:MM」

func secondsIn(_ str: String)->Int{ 
    var strArr = str.characters.split{$0 == ":"}.map(String.init) 
    var sec = Int(strArr[0])! * 3600 
    var sec1 = Int(strArr[1])! * 36 
    print("sec") 
    print(sec+sec1) 
    return sec+sec1 

} 

用法

var sec1 = secondsIn(shuttleTime) 
var sec2 = secondsIn(dateToString(Date())) 
print(sec1-sec2) 
+0

這個答案與操作的答案無關。 – 2017-04-09 07:04:46

0

這就是你如何得到最新版本Swift 3的區別

let calendar = NSCalendar.current 
var compos:Set<Calendar.Component> = Set<Calendar.Component>() 
compos.insert(.second) 
compos.insert(.minute) 
let difference = calendar.dateComponents(compos, from: fromDate, to: toDate) 
print("diff in minute=\(difference.minute!)") // difference in minute 
print("diff in seconds=\(difference.second!)") // difference in seconds 

參考:Getting the difference between two NSDates in (months/days/hours/minutes/seconds)

2

與弗雷迪的答案根據,這是功能快捷3:

let start = Date() 
     let enddt = Date(timeIntervalSince1970: 100) 
     let calendar = Calendar.current 
     let unitFlags = Set<Calendar.Component>([ .second]) 
     let datecomponenets = calendar.dateComponents(unitFlags, from: start, to: enddt) 
     let seconds = datecomponenets.second 
     print("Seconds: \(seconds)") 
+0

謝謝@LagMaster。很高興看到swift正在消除NS前綴。 – Freddy 2017-12-23 00:17:14

相關問題