web-dev-qa-db-fra.com

Trouvez la différence en secondes entre NSDates en entier à l'aide de Swift

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.

71
Erik

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.

166
Rob

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

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

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)")
2
Ahmed Safadi

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)

0
Rujoota Shah