2014-10-28 2 views
57

Я пишу фрагмент кода, где я хочу рассказать, как долго удерживалась кнопка. Для этого я записал NSDate() при нажатии кнопки и попытался использовать функцию timeIntervalSinceDate, когда кнопка была отпущена. Это похоже на работу, но я не могу найти способ распечатать результат или переключить его на целое.Найти разницу в секундах между NSDates как целое с помощью Swift

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

ответ

118

Произошла неправильная установка 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, но избегает некоторых своих сложностей, изложенных в Technical Q&A QA1398.

Помните, что CACurrentMediaTime/mach_absolute_time сбрасывается при перезагрузке устройства. Итак, в нижней строке, если вам нужны точные расчеты прошедшего времени во время работы приложения, используйте CACurrentMediaTime. Но если вы собираетесь сохранить это время начала в постоянном хранилище, которое вы могли бы вспомнить, когда приложение будет перезапущено в какой-то будущий день, тогда вы должны использовать Date или CFAbsoluteTimeGetCurrent и просто жить с любыми неточностями, которые могут возникнуть.

+3

Вау, спасибо Роб! Ваш ответ был очень полезным и понятным. Я очень ценю подсказку о CFAbsoluteTime. Я определенно буду использовать это! – Erik

+0

Каково измерение для timeIntervalSinceDate? – eugene

+1

Он возвращает ['NSTimeInterval'] (https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Miscellaneous/Foundation_DataTypes/index.html#//apple_ref/c/tdef/NSTimeInterval) , который измеряется как количество секунд. – Rob

19

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

Для Свифта 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) 
+0

Этот ответ не имеет отношения к ответу op. –

0

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

Ссылка: Getting the difference between two NSDates in (months/days/hours/minutes/seconds)

2

Согласно с ответом Фредди, это функция быстрой 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)") 
+0

Спасибо @LagMaster. Рад видеть, что быстро справляется с префиксом NS. – Freddy

 Смежные вопросы

  • Нет связанных вопросов^_^