Existe-t-il un moyen facile d'obtenir une heure très précisément?
J'ai besoin de calculer certains délais entre les appels de méthode. Plus précisément, je souhaite calculer la vitesse de défilement dans un UIScrollView.
Existe-t-il un moyen facile d'obtenir une heure très précisément?
J'ai besoin de calculer certains délais entre les appels de méthode. Plus précisément, je souhaite calculer la vitesse de défilement dans un UIScrollView.
Réponses:
NSDate
et lestimeIntervalSince*
méthodes renverront unNSTimeInterval
qui est un double avec une précision inférieure à la milliseconde.NSTimeInterval
est en secondes, mais il utilise le double pour vous donner une plus grande précision.Pour calculer la précision du temps en millisecondes, vous pouvez faire:
Documentation sur timeIntervalSinceNow .
Il existe de nombreuses autres façons de calculer cet intervalle en utilisant
NSDate
, et je recommanderaisNSDate
de consulter la documentation de classe pour laquelle se trouve dans NSDate Class Reference .la source
NSDate
etmach_absolute_time()
au niveau d'environ 30ms. 27 vs 29, 36 vs 39, 43 vs 45.NSDate
était plus facile à utiliser pour moi et les résultats étaient assez similaires pour ne pas s'en soucier.mach_absolute_time()
peut être utilisé pour obtenir des mesures précises.Voir http://developer.apple.com/qa/qa2004/qa1398.html
Est également disponible
CACurrentMediaTime()
, qui est essentiellement la même chose mais avec une interface plus facile à utiliser.(Remarque: cette réponse a été rédigée en 2009. Voir la réponse de Pavel Alexeev pour les
clock_gettime()
interfaces POSIX plus simples disponibles dans les nouvelles versions de macOS et iOS.)la source
CACurrentMediaTime()
, qui se convertitmach_absolute_time()
directement en fichierdouble
.elapsedNano
est de typeNanoseconds
, qui n'est pas un type entier. C'est un alias deUnsignedWide
, qui est une structure avec deux champs entiers 32 bits. Vous pouvez utiliser à laUnsignedWideToUInt64()
place du casting si vous préférez.Veuillez ne pas utiliser
NSDate
,CFAbsoluteTimeGetCurrent
ougettimeofday
pour mesurer le temps écoulé. Tout cela dépend de l'horloge système, qui peut changer à tout moment pour de nombreuses raisons différentes, telles que la synchronisation de l'heure du réseau (NTP), la mise à jour de l'horloge (il arrive souvent à s'ajuster à la dérive), les ajustements d'heure d'été, les secondes intercalaires, etc.Cela signifie que si vous mesurez votre vitesse de téléchargement ou de téléchargement, vous obtiendrez des pics ou des baisses soudaines de vos chiffres qui ne correspondent pas à ce qui s'est réellement passé; vos tests de performance auront des valeurs aberrantes incorrectes; et vos minuteries manuelles se déclencheront après des durées incorrectes. Le temps peut même reculer, et vous vous retrouvez avec des deltas négatifs, et vous pouvez vous retrouver avec une récursion infinie ou un code mort (oui, j'ai fait les deux).
Utilisez
mach_absolute_time
. Il mesure de vraies secondes depuis le démarrage du noyau. Il augmente de manière monotone (ne recule jamais) et n'est pas affecté par les paramètres de date et d'heure. Comme il est difficile de travailler avec, voici un simple wrapper qui vous donneNSTimeInterval
:la source
CACurrentMediaTime()
de QuartzCore?@import Darwin;
place de#include <mach/mach_time.h>
CFAbsoluteTimeGetCurrent()
renvoie le temps absolu sous forme dedouble
valeur, mais je ne sais pas quelle est sa précision - il peut ne se mettre à jour que toutes les douzaines de millisecondes, ou il peut se mettre à jour toutes les microsecondes, je ne sais pas.la source
72.89674947369
secondes serait assez rare, compte tenu de toutes les autres valeurs qu'elle pourrait être. ;)Je n'utiliserais PAS
mach_absolute_time()
car il interroge une combinaison du noyau et du processeur pendant un temps absolu en utilisant des ticks (probablement un temps de disponibilité).Ce que j'utiliserais:
Cette fonction est optimisée pour corriger la différence entre le logiciel et le matériel iOS et OSX.
Quelque chose de geekier
Le quotient d'une différence entre
mach_absolute_time()
etAFAbsoluteTimeGetCurrent()
est toujours autour de 24000011.154871Voici un journal de mon application:
S'il vous plaît noter que le temps de résultat final est une différence dans
CFAbsoluteTimeGetCurrent()
« sla source
mach_absolute_time()
avec unmach_timebase_info_data
et puis je l'ai fait(long double)((mach_absolute_time()*time_base.numer)/((1000*1000)*time_base.denom));
. Pour obtenir la base de temps mach, vous pouvez faire(void)mach_timebase_info(&your_timebase);
Usage:
Production:
la source
NSDate
dépend de l'horloge du système qui peut être modifiée à tout moment, ce qui peut entraîner des intervalles de temps erronés ou même négatifs. Utilisez à lamach_absolute_time
place pour obtenir le temps écoulé correct.mach_absolute_time
peut être affecté par les redémarrages de l'appareil. Utilisez plutôt l'heure du serveur.Aussi, voici comment calculer un 64 bits
NSNumber
initialisé avec l'époque Unix en millisecondes, au cas où vous voudriez le stocker dans CoreData. J'en avais besoin pour mon application qui interagit avec un système qui stocke les dates de cette façon.la source
Les fonctions basées sur
mach_absolute_time
sont bonnes pour les mesures courtes.Mais pour les longues mesures, une mise en garde importante est qu'ils cessent de tourner pendant que l'appareil est en veille.
Il existe une fonction pour obtenir le temps depuis le démarrage. Cela ne s'arrête pas pendant le sommeil. De plus, ce
gettimeofday
n'est pas monotone, mais dans mes expériences, j'ai toujours vu que l'heure de démarrage change lorsque l'heure du système change, donc je pense que cela devrait fonctionner correctement.Et depuis iOS 10 et macOS 10.12, nous pouvons utiliser CLOCK_MONOTONIC:
Résumer:
Date.timeIntervalSinceReferenceDate
- change lorsque l'heure du système change, pas monotoneCFAbsoluteTimeGetCurrent()
- pas monotone, peut revenir en arrièreCACurrentMediaTime()
- arrête de tic-tac lorsque l'appareil est en veilletimeSinceBoot()
- ne dort pas, mais n'est peut-être pas monotoneCLOCK_MONOTONIC
- ne dort pas, monotone, pris en charge depuis iOS 10la source
Je sais que c'est un ancien, mais même moi, je me suis retrouvé à errer à nouveau, alors j'ai pensé que je soumettrais ma propre option ici.
Le mieux est de consulter mon article de blog à ce sujet: Chronométrage en Objective-C: Un chronomètre
Fondamentalement, j'ai écrit une classe qui arrête de regarder de manière très basique mais qui est encapsulée afin que vous n'ayez qu'à faire ce qui suit:
Et vous vous retrouvez avec:
dans le journal ...
Encore une fois, consultez mon article pour un peu plus ou téléchargez-le ici: MMStopwatch.zip
la source
NSDate
dépend de l'horloge du système qui peut être modifiée à tout moment, ce qui peut entraîner des intervalles de temps erronés ou même négatifs. Utilisez à lamach_absolute_time
place pour obtenir le temps écoulé correct.Vous pouvez obtenir l'heure actuelle en millisecondes depuis le 1er janvier 1970 en utilisant un NSDate:
la source
Pour ceux-ci, nous avons besoin de la version Swift de la réponse de @Jeff Thompson:
J'espère que cela vous aidera.
la source
NSDate
dépend de l'horloge du système qui peut être modifiée à tout moment, ce qui peut entraîner des intervalles de temps erronés ou même négatifs. Utilisez à lamach_absolute_time
place pour obtenir le temps écoulé correct.