使用Swift查找NSDate作为整数的秒之间的差异


98

我正在编写一段代码,我想在其中计时按下按钮的时间。为此,我记录了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 = ???
}

我已经看到了一些类似的问题,但是我不了解C,所以我很难理解给出的答案。如果有一种更有效的方法来找出按下按钮的时间,我欢迎您提出建议。提前致谢。

Answers:


214

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

let elapsed = Date().timeIntervalSince(timeAtPress)

请注意参考()之后的内容Date。该Date()实例化一个新的日期对象,然后timeIntervalSince返回和之间的时间差timeAtPress。这将返回一个浮点值(技术上为a 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但避免了技术问答QA1398中概述的某些复杂性。

不过请记住,重启设备时CACurrentMediaTime/ mach_absolute_time将会重置。因此,最重要的是,如果您在运行应用程序时需要准确的经过时间计算,请使用CACurrentMediaTime。但是,如果您打算将此开始时间保存在永久性存储中,您可能会在以后某个日期重新启动该应用程序时想起该时间,那么您必须使用DateCFAbsoluteTimeGetCurrent,并且要承受可能带来的任何不准确之处。


4
哇,谢谢罗布!您的回答非常有帮助且易于理解。我非常感谢有关CFAbsoluteTime的技巧。我一定会用的!
Erik 2014年

timeIntervalSinceDate的维数是多少?
尤金(Eugene)2015年

它返回TimeInterval,以秒为单位。
罗布

22

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)")

由于某种原因,即使日期相隔一个小时,它也总是为我返回0。
Markymark

10

根据弗雷迪的回答,这是迅速的功能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))

1
谢谢@LagMaster。很高兴看到swift取消了NS前缀。
弗雷迪

4

迅捷5

let differenceInSeconds = Int(endDate.timeIntervalSince(startDate))

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

参考:得到两个NSD日期之间的差异(月/天/小时/分钟/分钟/秒)


-1

迅捷5

    let startDate = Date()
    let endDate = Date()
    let calendar = Calendar.current
    let dateComponents = calendar.compare(startDate, to: endDate, toGranularity: .second)
    let seconds = dateComponents.rawValue
    print("Seconds: \(seconds)")

2
无论起始点是否更大,这都不会提供代码的秒数差异。
阿伦K

-6

在2时之间以“ hh:mm”间隔3秒

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)

这个答案与操作的答案无关。
Tomasz Nazarenko
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.