Find difference in seconds between NSDates as integer using Swift
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.
Swift 5
let differenceInSeconds = Int(endDate.timeIntervalSince(startDate))
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)")