Найти разницу в секундах между 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, поэтому мне было трудно понять ответы. Если есть более эффективный способ узнать, как долго кнопка удерживалась, я открыт для предложений. Заранее спасибо.

5 ответов

Решение

Ваша попытка рассчитать elapsedTime это неверно. В Swift 3 это будет:

let elapsed = Date().timeIntervalSince(timeAtPress)

Обратите внимание () после Date ссылка. Date() создает новый объект даты, а затем timeIntervalSince возвращает разницу во времени между этим и timeAtPress, Это вернет значение с плавающей запятой (технически, 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, Но если вы собираетесь сохранить это время запуска в постоянном хранилище, которое вы можете вспомнить, когда приложение будет перезапущено в будущем, вам придется использовать Date или же CFAbsoluteTimeGetCurrent и просто жить с любыми неточностями, которые могут повлечь за собой.

Swift 5

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

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:

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

Вот как вы можете получить разницу в последней версии 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

Ссылка: Получение разницы между двумя NSDates в (месяцы / дни / часы / минуты / секунды)

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 3 секунды между 2 раза в "чч: мм"

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)
Другие вопросы по тегам