Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find difference in seconds between NSDates as integer using Swift

I'm writing a piece of code where I want to time how long a button was held down. To do that I recorded an NSDate() when the button was pressed, and tried using the timeIntervalSinceDate function when the button was released. That seems to work but I can't find any way to print the result or switch it to an integer.

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 = ??? } 

I've seen a few similar questions, but I don't know C so I had a hard time understanding the answers given. If there is a more efficient way to find out how long the button was held down I'm open to suggestions. Thanks in advance.

like image 609
Erik Avatar asked Oct 28 '14 00:10

Erik


People also ask

How do I get time difference in seconds in Swift?

To calculate the time difference between two Date objects in seconds in Swift, use the Date. timeIntervalSinceReferenceDate method.

How do you find the difference in timestamps?

Discussion: If you'd like to calculate the difference between the timestamps in seconds, multiply the decimal difference in days by the number of seconds in a day, which equals 24 * 60 * 60 = 86400 , or the product of the number of hours in a day, the number of minutes in an hour, and the number of seconds in a minute.

How do I get todays date in Swift?

Get current time in “YYYY-MM–DD HH:MM:SS +TIMEZONE” format in Swift. This is the easiest way to show the current date-time.


1 Answers

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.

like image 197
Rob Avatar answered Oct 08 '22 18:10

Rob