J'écris un morceau de code où je veux chronométrer combien de temps un bouton a été maintenu enfoncé. Pour ce faire, j’ai enregistré NSDate()
lorsque le bouton a été enfoncé et essayé d’utiliser la fonction timeIntervalSinceDate
lorsque le bouton a été relâché. Cela semble fonctionner, mais je ne trouve aucun moyen d'imprimer le résultat ou de le convertir en entier.
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 = ???
}
J'ai vu quelques questions similaires, mais je ne sais pas C, alors j'ai eu du mal à comprendre les réponses données. S'il existe un moyen plus efficace de savoir combien de temps le bouton a été enfoncé, je suis ouvert aux suggestions. Merci d'avance.
Votre tentative de calcul de elapsedTime
est incorrecte. Dans Swift 3, ce serait:
let elapsed = Date().timeIntervalSince(timeAtPress)
Notez le ()
après la référence Date
. Date()
instancie un nouvel objet de date, puis timeIntervalSince
renvoie l'écart horaire entre cet objet et timeAtPress
Cela renverra une valeur à virgule flottante (techniquement, une TimeInterval
).
Si vous voulez que cela soit tronqué à une valeur Int
, vous pouvez simplement utiliser:
let duration = Int(elapsed)
Et, BTW, votre définition de la variable timeAtPress
n'a pas besoin d'instancier un objet Date
. Je présume que vous aviez l'intention de:
var timeAtPress: Date!
Cela définit la variable comme étant une variable Date
(implicitement non enveloppée), mais vous différeriez probablement l’instanciation réelle de cette variable jusqu’à ce que pressed
soit appelé.
Alternativement, j'utilise souvent CFAbsoluteTimeGetCurrent()
, par exemple,
var start: CFAbsoluteTime!
Et lorsque je veux définir startTime
, je procède comme suit:
start = CFAbsoluteTimeGetCurrent()
Et quand je veux calculer le nombre de secondes écoulées, je fais ce qui suit:
let elapsed = CFAbsoluteTimeGetCurrent() - start
Il est à noter que la documentation CFAbsoluteTimeGetCurrent
nous avertit:
Des appels répétés à cette fonction ne garantissent pas des résultats en augmentation monotone. L'heure du système peut diminuer en raison d'une synchronisation avec des références de temps externes ou d'un changement explicite de l'horloge par l'utilisateur.
Cela signifie que si vous êtes assez malheureux pour mesurer le temps écoulé lorsqu'un de ces ajustements a lieu, vous pouvez vous retrouver avec un calcul de temps écoulé incorrect. Cela vaut également pour les calculs NSDate
/Date
. Il est plus sûr d'utiliser un calcul basé sur mach_absolute_time
(le plus facilement possible avec CACurrentMediaTime
):
let start = CACurrentMediaTime()
et
let elapsed = CACurrentMediaTime() - start
Ceci utilise mach_absolute_time
, mais évite certaines des complexités décrites dans Questions techniques (QA) QA1398 .
Rappelez-vous cependant que CACurrentMediaTime
/mach_absolute_time
sera réinitialisé lors du redémarrage du périphérique. Ainsi, si vous avez besoin de calculs de temps écoulé précis pendant l'exécution d'une application, utilisez CACurrentMediaTime
. Toutefois, si vous souhaitez enregistrer cette heure de démarrage dans un stockage persistant dont vous vous souviendrez peut-être lorsque l'application sera redémarrée à une date ultérieure, vous devez utiliser Date
ou CFAbsoluteTimeGetCurrent
et survivre avec toutes les inexactitudes que cela peut entraîner.
NSDate () et NSCalendar () semblent être un bon choix. Utilisez le calcul du calendrier et laissez la partie mathématique réelle dans le cadre. Voici un exemple rapide d’obtention des secondes entre deux 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)")
Selon la réponse de Freddy, voici la fonction de Swift 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 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)")
Voici comment vous pouvez obtenir la différence dans la dernière version de 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
Référence: Obtenir la différence entre deux NSDates en (mois/jours/heures/minutes/secondes)