iPhone: comment obtenir les millisecondes actuelles?


Réponses:


274
[[NSDate date] timeIntervalSince1970];

Il renvoie le nombre de secondes depuis l'époque sous forme de double. Je suis presque sûr que vous pouvez accéder aux millisecondes à partir de la partie fractionnaire.


29
cela ne tue personne de l'écrire comme ceci: NSTimeInterval myInterval = NSDate.timeIntervalSince1970; // tous ces crochets sont vraiment démodés si vous me le demandez.
Pizzaiola Gorgonzola

11
'ces parenthèses' sont une version plus récente de la syntaxe selon stackoverflow.com/q/11474284/209828
Matthew

119
"ces crochets" sont objectifs-c. Si vous souhaitez développer pour iOS, vous devriez probablement vous familiariser avec eux.
Ampers4nd

5
J'utilise cette méthode depuis un certain temps et j'ai réalisé qu'elle peut retourner une valeur antérieure lorsque vous l'appelez après quelques millisecondes (par exemple, appelez-la consécutivement et vous pourriez ne pas vous retrouver avec une séquence croissante)
Ege Akpinar

5
[NSDate timeIntervalSinceReferenceDate]est moins cher. (Bien qu'il fasse référence à une "époque" différente - si vous voulez 1970, ajoutez la constante NSTimeIntervalSince1970.)
Hot Licks

311

Si vous envisagez d'utiliser ceci pour un timing relatif (par exemple pour les jeux ou l'animation), je préfère utiliser CACurrentMediaTime ()

double CurrentTime = CACurrentMediaTime();

Quelle est la voie recommandée; NSDates'inspire de l'horloge de synchronisation en réseau et occasionnellement un hoquet lors de la resynchronisation avec le réseau.

Il renvoie l'heure absolue actuelle, en secondes.


Si vous ne voulez que la partie décimale (souvent utilisée lors de la synchronisation des animations),

let ct = CACurrentMediaTime().truncatingRemainder(dividingBy: 1)

7
Mais cela semble prendre le double du temps nécessaire pour [[NSDate date] timeIntervalSince1970]. J'ai mesuré 0,065 ms contre 0,033 ms sur 15 000 appels.
Kay

1
Remarque, vous devrez inclure Quartz Framework et #import <Quartz / CABase.h> pour effectuer cet appel.
BadPirate

8
Oups - c'est l'importation #import <QuartzCore / CAAnimation.h>
BadPirate

6
Pour ceux qui découvrent Xcode (comme moi) "inclure Quartz Framework" signifie l'ajouter à l'ensemble de bibliothèques dans "Link Binary With Libraries".
Gabe Johnson

3
Si quelqu'un le recherche par rapport à SpriteKit, «l'heure actuelle» dans la méthode de mise à jour de SKScene est bien le CACurrentMediaTime ();
Anthony Mattox

92

J'ai comparé toutes les autres réponses sur un iPhone 4S et iPad 3 (versions de version). CACurrentMediaTimea le moins de frais généraux par une petite marge. timeIntervalSince1970est beaucoup plus lent que les autres, probablement en raison de la NSDatesurcharge d'instanciation, bien que cela puisse ne pas avoir d'importance pour de nombreux cas d'utilisation.

Je recommanderais CACurrentMediaTimesi vous voulez le moins de frais généraux et que cela ne vous dérange pas d'ajouter la dépendance Quartz Framework. Ou gettimeofdaysi la portabilité est une priorité pour vous.

iphone 4s

CACurrentMediaTime: 1.33 µs/call
gettimeofday: 1.38 µs/call
[NSDate timeIntervalSinceReferenceDate]: 1.45 µs/call
CFAbsoluteTimeGetCurrent: 1.48 µs/call
[[NSDate date] timeIntervalSince1970]: 4.93 µs/call

iPad 3

CACurrentMediaTime: 1.25 µs/call
gettimeofday: 1.33 µs/call
CFAbsoluteTimeGetCurrent: 1.34 µs/call
[NSDate timeIntervalSinceReferenceDate]: 1.37 µs/call
[[NSDate date] timeIntervalSince1970]: 3.47 µs/call

1
+1, Bien que cela soit évidemment très instructif et utile, je ne dirais pas exactement que c'est un excellent travail d'ingénierie sans voir du code source;)
Steven Lu

2
Attention cependant à ce problème: bendodson.com/weblog/2013/01/29/ca-current-media-time Cette horloge s'arrête apparemment lorsque l'appareil se met en veille.
mojuba

1
Il y a la NSTimeIntervalSince1970macro qui est la plus rapide.
ozgur

@ozgur NSTimeIntervalSince1970est une constante décrivant les secondes entre 1970-01-01 et la "date de référence" (c.-à-d. 2001-01-01), elle est donc toujours égale à 978307200
YourMJK

53

Dans Swift, nous pouvons créer une fonction et procéder comme suit

func getCurrentMillis()->Int64{
    return  Int64(NSDate().timeIntervalSince1970 * 1000)
}

var currentTime = getCurrentMillis()

Bien que son beau travail à Swift 3.0 , mais nous pouvons modifier et utiliser la Dateclasse à la place de NSDatedans 3.0

Swift 3.0

func getCurrentMillis()->Int64 {
    return Int64(Date().timeIntervalSince1970 * 1000)
}

var currentTime = getCurrentMillis()

30

Jusqu'à présent, j'ai trouvé gettimeofdayune bonne solution sur iOS (iPad), lorsque vous souhaitez effectuer une évaluation d'intervalle (par exemple, la fréquence d'images, le timing d'une image de rendu ...):

#include <sys/time.h>
struct timeval time;
gettimeofday(&time, NULL);
long millis = (time.tv_sec * 1000) + (time.tv_usec / 1000);

2
J'aime aussi ça car c'est très portable. Notez que selon le système d'exploitation, vous devrez peut-être utiliser «long long» au lieu d'un «long» et également cast time.tv_sec à «long long» avant de faire le reste du calcul.
AbePralle

statique non signé long getMStime (void) {struct timeval time; gettimeofday (& time, NULL); return (time.tv_sec * 1000) + (time.tv_usec / 1000); }
David H

Fait intéressant, cela fonctionne bien sur mon iPhone 5S et Mac, mais renvoie une mauvaise valeur sur un iPad 3.
Hyndrix

Afin d'éviter d'obtenir des nombres négatifs, j'ai dû lancer avant le calcul: résultat int64_t = ((int64_t) tv.tv_sec * 1000) + ((int64_t) tv.tv_usec / 1000);
jason gilbert

il retourne l'heure en -ve
Shauket Sheikh

23

Pour obtenir des millisecondes pour la date actuelle.

Swift 4+:

func currentTimeInMilliSeconds()-> Int
    {
        let currentDate = Date()
        let since1970 = currentDate.timeIntervalSince1970
        return Int(since1970 * 1000)
    }

18

Swift 2

let seconds = NSDate().timeIntervalSince1970
let milliseconds = seconds * 1000.0

Swift 3

let currentTimeInMiliseconds = Date().timeIntervalSince1970.milliseconds

2
TimeIntervalaka Doublen'a pas de propriété en millisecondes. Date().timeIntervalSince1970 * 1000
Leo Dabus

10

Il peut être utile de connaître CodeTimestamps, qui fournit un wrapper autour des fonctions de synchronisation basées sur les machines. Cela vous donne des données de synchronisation de résolution en nanosecondes - 1000000x plus précises que les millisecondes. Oui, un million de fois plus précis. (Les préfixes sont milli, micro, nano, chacun 1000x plus précis que le précédent.) Même si vous n'avez pas besoin de CodeTimestamps, consultez le code (c'est open source) pour voir comment ils utilisent mach pour obtenir les données de synchronisation. Cela serait utile lorsque vous avez besoin de plus de précision et que vous souhaitez un appel de méthode plus rapide que l'approche NSDate.

http://eng.pulse.me/line-by-line-speed-analysis-for-ios-apps/


Et vous en aurez probablement besoin -fno-objc-arcsi vous utilisez ARC :)
Dan Rosenstark


3
Le code source lié depuis la page est ici: github.com/tylerneylon/moriarty
Tomas Andrle

8
// Timestamp after converting to milliseconds.

NSString * timeInMS = [NSString stringWithFormat:@"%lld", [@(floor([date timeIntervalSince1970] * 1000)) longLongValue]];

6

J'avais besoin d'un NSNumberobjet contenant le résultat exact de [[NSDate date] timeIntervalSince1970]. Étant donné que cette fonction a été appelée plusieurs fois et que je n'avais pas vraiment besoin de créer un NSDateobjet, les performances n'étaient pas excellentes.

Donc, pour obtenir le format que la fonction d'origine me donnait, essayez ceci:

#include <sys/time.h>
struct timeval tv;
gettimeofday(&tv,NULL);
double perciseTimeStamp = tv.tv_sec + tv.tv_usec * 0.000001;

Ce qui devrait vous donner exactement le même résultat que [[NSDate date] timeIntervalSince1970]


4

CFAbsoluteTimeGetCurrent ()

Le temps absolu est mesuré en secondes par rapport à la date de référence absolue du 1er janvier 2001 00:00:00 GMT. Une valeur positive représente une date après la date de référence, une valeur négative représente une date antérieure. Par exemple, l'heure absolue -32940326 équivaut au 16 décembre 1999 à 17:54:34. Les appels répétés à cette fonction ne garantissent pas une augmentation monotone des résultats. L'heure système peut diminuer en raison de la synchronisation avec des références temporelles externes ou en raison d'un changement explicite de l'horloge par l'utilisateur.


4

Essaye ça :

NSDate * timestamp = [NSDate dateWithTimeIntervalSince1970:[[NSDate date] timeIntervalSince1970]];

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"YYYY-MM-dd HH:mm:ss.SSS"];

NSString *newDateString = [dateFormatter stringFromDate:timestamp];
timestamp = (NSDate*)newDateString;

Dans cet exemple, dateWithTimeIntervalSince1970 est utilisé en combinaison du formateur @ "YYYY-MM-dd HH: mm: ss.SSS" qui renverra la date avec l'année, le mois, le jour et l'heure avec les heures, les minutes, les secondes et les millisecondes . Voir l'exemple: "2015-12-02 04: 43: 15.008". J'ai utilisé la NSString pour être sûr que le format sera écrit auparavant.


4

Il s'agit essentiellement de la même réponse que celle publiée par @TristanLorach, juste recodée pour Swift 3:

   /// Method to get Unix-style time (Java variant), i.e., time since 1970 in milliseconds. This 
   /// copied from here: http://stackoverflow.com/a/24655601/253938 and here:
   /// http://stackoverflow.com/a/7885923/253938
   /// (This should give good performance according to this: 
   ///  http://stackoverflow.com/a/12020300/253938 )
   ///
   /// Note that it is possible that multiple calls to this method and computing the difference may 
   /// occasionally give problematic results, like an apparently negative interval or a major jump 
   /// forward in time. This is because system time occasionally gets updated due to synchronization 
   /// with a time source on the network (maybe "leap second"), or user setting the clock.
   public static func currentTimeMillis() -> Int64 {
      var darwinTime : timeval = timeval(tv_sec: 0, tv_usec: 0)
      gettimeofday(&darwinTime, nil)
      return (Int64(darwinTime.tv_sec) * 1000) + Int64(darwinTime.tv_usec / 1000)
   }

2
 func currentmicrotimeTimeMillis() -> Int64{
let nowDoublevaluseis = NSDate().timeIntervalSince1970
return Int64(nowDoublevaluseis*1000)

}


1

C'est ce que j'ai utilisé pour Swift

var date = NSDate()
let currentTime = Int64(date.timeIntervalSince1970 * 1000)

print("Time in milliseconds is \(currentTime)")

utilisé ce site pour vérifier l'exactitude http://currentmillis.com/


1
let timeInMiliSecDate = Date()
let timeInMiliSec = Int (timeInMiliSecDate.timeIntervalSince1970 * 1000)
print(timeInMiliSec)

Veuillez ajouter quelques explications à votre code afin que d'autres puissent en tirer des leçons - surtout si vous postez une réponse à une question qui a déjà beaucoup de réponses votées
Nico Haase

0

[NSDate timeIntervalSinceReferenceDate]est une autre option, si vous ne souhaitez pas inclure le framework Quartz. Il renvoie un double, représentant les secondes.


0
NSTimeInterval time = ([[NSDate date] timeIntervalSince1970]); //double
long digits = (long)time; //first 10 digits        
int decimalDigits = (int)(fmod(time, 1) * 1000); //3 missing digits
/*** long ***/
long timestamp = (digits * 1000) + decimalDigits;
/*** string ***/
NSString *timestampString = [NSString stringWithFormat:@"%ld%03d",digits ,decimalDigits];
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.