2014-10-28 55 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

相关问题