使用 Swift 以整数形式查找 NSDates 之间的秒差

我正在写一段代码,计算按钮按下的时间。为了做到这一点,我记录了按钮时的 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,所以我很难理解给出的答案。如果有一个更有效的方法来找出按钮按下了多长时间,我愿意接受建议。先谢谢你。

88742 次浏览

Your attempt to calculate elapsedTime is incorrect. In Swift 3, it would be:

let elapsed = Date().timeIntervalSince(timeAtPress)

Note the () after the Date reference. The Date() instantiates a new date object, and then timeIntervalSince returns the time difference between that and timeAtPress. That will return a floating point value (technically, a TimeInterval).

If you want that as truncated to a Int value, you can just use:

let duration = Int(elapsed)

And, BTW, your definition of the timeAtPress variable doesn't need to instantiate a Date object. I presume you intended:

var timeAtPress: Date!

That defines the variable as a Date variable (an implicitly unwrapped one), but you'd presumably defer the actual instantiation of that variable until pressed is called.


Alternatively, I often use CFAbsoluteTimeGetCurrent(), e.g.,

var start: CFAbsoluteTime!

And when I want to set startTime, I do the following:

start = CFAbsoluteTimeGetCurrent()

And when I want to calculate the number of seconds elapsed, I do the following:

let elapsed = CFAbsoluteTimeGetCurrent() - start

It's worth noting that the CFAbsoluteTimeGetCurrent documentation warns us:

Repeated calls to this function do not guarantee monotonically increasing results. The system time may decrease due to synchronization with external time references or due to an explicit user change of the clock.

This means that if you're unfortunate enough to measure elapsed time when one of these adjustments take place, you can end up with incorrect elapsed time calculation. This is true for NSDate/Date calculations too. It's safest to use a mach_absolute_time based calculation (most easily done with CACurrentMediaTime):

let start = CACurrentMediaTime()

and

let elapsed = CACurrentMediaTime() - start

This uses mach_absolute_time, but avoids some of its complexities outlined in Technical Q&A QA1398.

Remember, though, that CACurrentMediaTime/mach_absolute_time will be reset when the device is rebooted. So, bottom line, if you need accurate elapsed time calculations while an app is running, use CACurrentMediaTime. But if you're going to save this start time in persistent storage which you might recall when the app is restarted at some future date, then you have to use Date or CFAbsoluteTimeGetCurrent, and just live with any inaccuracies that may entail.

NSDate() and NSCalendar() sound like a good choice. Use calendar calculation and leave the actual math part to the framework. Here is a quick example of getting the seconds between two 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)")

For Swift 3 Seconds between 2 time in "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


}

Usage

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

This is how you can get the difference in latest version of 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

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

According with the Freddy's answer, this is the function in swift 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))

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

Swift 5

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