Найти разницу в секундах между NSDates как целое с помощью 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 = ???
}
Я видел несколько подобных вопросов, но я не знаю C, поэтому мне было трудно понять ответы. Если есть более эффективный способ узнать, как долго удерживалась кнопка, я открыт для предложений. Спасибо заранее.
Ответы
Ответ 1
Ваша попытка вычисления elapsedTime
неверна. В Swift 3 это будет:
let elapsed = Date().timeIntervalSince(timeAtPress)
Обратите внимание на ()
после ссылки Date
. Date()
создает новый объект даты, а затем timeIntervalSince
возвращает разницу во времени между тем и timeAtPress
. Это вернет значение с плавающей запятой (технически, TimeInterval
).
Если вы хотите, чтобы это было усечено до значения Int
, вы можете просто использовать:
let duration = Int(elapsed)
И, BTW, вашему определению переменной 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
, но избегает некоторых его сложностей, изложенных в Technical Q & A QA1398.
Помните, что при перезагрузке устройства CACurrentMediaTime
/mach_absolute_time
будет reset. Итак, в нижней строке, если вам нужны точные расчеты прошедшего времени во время работы приложения, используйте CACurrentMediaTime
. Но если вы собираетесь сохранить это время начала в постоянном хранилище, которое вы могли бы вспомнить, когда приложение будет перезапущено в какой-то будущий день, тогда вы должны использовать Date
или CFAbsoluteTimeGetCurrent
и просто жить с любыми неточностями, которые могут повлечь за собой.
Ответ 2
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)")
Ответ 3
Согласно ответу Фредди, это функция в быстрой 3:
let start = Date()
let enddt = Date(timeIntervalSince1970: 100)
let calendar = Calendar.current
let unitFlags = Set<Calendar.Component>([ .second])
let datecomponenets = calendar.dateComponents(unitFlags, from: start, to: enddt)
let seconds = datecomponenets.second
print("Seconds: \(seconds)")
Ответ 4
Вот как вы можете получить разницу в последней версии 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
Ссылка: Получение разницы между двумя NSDate в (месяцы/дни/часы/минуты/секунды)
Ответ 5
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)")
Ответ 6
Для Swift 3
Секунды между 2-х раз в "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
}
Использование
var sec1 = secondsIn(shuttleTime)
var sec2 = secondsIn(dateToString(Date()))
print(sec1-sec2)