使用Swift查找NSDates之间以秒为单位的差异

Eri*_*rik 93 nsdate nstimeinterval swift

我正在写一段代码,我想要按下按钮的时间.为此,我NSDate()在按下按钮时录制了一个按钮,并timeIntervalSinceDate在释放按钮时尝试使用该功能.这似乎工作,但我找不到任何方法来打印结果或将其切换为整数.

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 = ???
}
Run Code Online (Sandbox Code Playgroud)

我见过几个类似的问题,但我不知道C所以我很难理解给出的答案.如果有更有效的方法来确定按钮被按下多长时间,我愿意接受建议.提前致谢.

Rob*_*Rob 196

您的计算尝试elapsedTime不正确.在Swift 3中,它将是:

let elapsed = Date().timeIntervalSince(timeAtPress)
Run Code Online (Sandbox Code Playgroud)

请注意参考()后的内容Date.该Date()实例化一个新的日期对象,然后timeIntervalSince返回和之间的时间差timeAtPress.这将返回浮点值(技术上,a TimeInterval).

如果您希望将其截断为Int值,则可以使用:

let duration = Int(elapsed)
Run Code Online (Sandbox Code Playgroud)

而且,BTW,您对timeAtPress变量的定义不需要实例化Date对象.我认为你打算:

var timeAtPress: Date!
Run Code Online (Sandbox Code Playgroud)

它将变量定义为Date变量(隐式展开的变量),但是在pressed调用之前,您可能会推迟该变量的实际实例化.


或者,我经常使用CFAbsoluteTimeGetCurrent(),例如,

var start: CFAbsoluteTime!
Run Code Online (Sandbox Code Playgroud)

当我想要设置时startTime,我会执行以下操作:

start = CFAbsoluteTimeGetCurrent()
Run Code Online (Sandbox Code Playgroud)

当我想计算经过的秒数时,我会执行以下操作:

let elapsed = CFAbsoluteTimeGetCurrent() - start
Run Code Online (Sandbox Code Playgroud)

值得注意的是,CFAbsoluteTimeGetCurrent文档警告我们:

重复调用此函数并不能保证单调增加结果.由于与外部时间参考同步或由于时钟的明确用户改变,系统时间可能减少.

这意味着如果您不幸测量其中一次调整所经过的时间,则最终可能会计算出错误的经过时间.对于NSDate/ Date计算也是如此.使用mach_absolute_time基于计算的最安全(最容易完成CACurrentMediaTime):

let start = CACurrentMediaTime()
Run Code Online (Sandbox Code Playgroud)

let elapsed = CACurrentMediaTime() - start
Run Code Online (Sandbox Code Playgroud)

这样可以使用mach_absolute_time,但避免了技术问答QA1398中概述的一些复杂性.

但请记住,当重启设备时,CACurrentMediaTime/ mach_absolute_time将重置.因此,如果您需要在应用程序运行时进行准确的经过时间计算,请使用底线CACurrentMediaTime.但是,如果您要将此开始时间保存在持久存储中,而您可能会在将来某个日期重新启动该应用程序时将其记住,那么您必须使用Date或者使用CFAbsoluteTimeGetCurrent可能带来的任何不准确之处.

  • 哇,谢谢Rob!您的回答非常有用且易于理解.我非常感谢有关CFAbsoluteTime的提示.我肯定会用它! (4认同)

Fre*_*ddy 21

NSDate()和NSCalendar()听起来是个不错的选择.使用日历计算并将实际的数学部分留给框架.以下是获取两者之间秒数的快速示例NSDate()

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)")
Run Code Online (Sandbox Code Playgroud)


iKK*_*iKK 11

斯威夫特 5

let differenceInSeconds = Int(endDate.timeIntervalSince(startDate))
Run Code Online (Sandbox Code Playgroud)


And*_*nes 7

根据弗雷迪的回答,这是迅速的功能3:

let start = Date()
let end = Date(timeIntervalSince1970: 100)
let calendar = Calendar.current
let unitFlags = Set<Calendar.Component>([ .second])
let datecomponents = calendar.dateComponents(unitFlags, from: start, to: end)
let seconds = datecomponents.second
print(String(describing: seconds))
Run Code Online (Sandbox Code Playgroud)