Comment obtenir l'heure actuelle en millisecondes depuis C sous Linux?


86

Comment obtenir l'heure actuelle sous Linux en millisecondes?

Réponses:


100

Ceci peut être réalisé en utilisant la fonction POSIXclock_gettime .

Dans la version actuelle de POSIX, gettimeofdayest marqué comme obsolète . Cela signifie qu'il peut être supprimé d'une future version de la spécification. Les développeurs d'applications sont encouragés à utiliser la clock_gettimefonction à la place de gettimeofday.

Voici un exemple d'utilisation clock_gettime:

#define _POSIX_C_SOURCE 200809L

#include <inttypes.h>
#include <math.h>
#include <stdio.h>
#include <time.h>

void print_current_time_with_ms (void)
{
    long            ms; // Milliseconds
    time_t          s;  // Seconds
    struct timespec spec;

    clock_gettime(CLOCK_REALTIME, &spec);

    s  = spec.tv_sec;
    ms = round(spec.tv_nsec / 1.0e6); // Convert nanoseconds to milliseconds
    if (ms > 999) {
        s++;
        ms = 0;
    }

    printf("Current time: %"PRIdMAX".%03ld seconds since the Epoch\n",
           (intmax_t)s, ms);
}

Si votre objectif est de mesurer le temps écoulé et que votre système prend en charge l'option «horloge monotone», vous devriez envisager d'utiliser CLOCK_MONOTONICau lieu de CLOCK_REALTIME.


7
+1 pour être POSIXly correct - mais votre réponse a les mauvaises unités. L'OP ne veut pas l'heure en millisecondes, mais l'heure en millisecondes.
pilcrow

5
Bonne solution mais n'oubliez pas le -lm dans votre gcccommande.
David Guyon

2
selon la page de manuel pour round, vous voulez utiliser lround lors de l'affectation du résultat à un entier (ou long)
hildred

2
Vous devez utiliser floor () au lieu de round () pour ne jamais arrondir à 1000 ms. Sinon, vous devrez incrémenter slorsque cela se produit. Probablement un événement rare, mais le chiffre supplémentaire peut causer des problèmes.
Mike

1
@Mike Belle prise. À un sur deux mille, ce n'est même pas si rare et devrait donc être résolu. Plutôt que d'utiliser le sol, je pense que je préfère conserver un peu plus de précision et continuer à arrondir, mais incrémenter le deuxième compteur s'il arrondit à 1000.
Dan Molding

58

Vous devez faire quelque chose comme ceci:

struct timeval  tv;
gettimeofday(&tv, NULL);

double time_in_mill = 
         (tv.tv_sec) * 1000 + (tv.tv_usec) / 1000 ; // convert tv_sec & tv_usec to millisecond

33

Voici la fonction util pour obtenir l'horodatage actuel en millisecondes:

#include <sys/time.h>

long long current_timestamp() {
    struct timeval te; 
    gettimeofday(&te, NULL); // get current time
    long long milliseconds = te.tv_sec*1000LL + te.tv_usec/1000; // calculate milliseconds
    // printf("milliseconds: %lld\n", milliseconds);
    return milliseconds;
}

À propos du fuseau horaire :

gettimeofday () pour spécifier le fuseau horaire, j'utilise NULL , qui ignore le fuseau horaire, mais vous pouvez spécifier un fuseau horaire, si besoin.


@Update - fuseau horaire

Puisque la longreprésentation du temps n'est pas pertinente ou affectée par le fuseau horaire lui-même, il tzn'est pas nécessaire de définir le paramètre de gettimeofday (), car cela ne fera aucune différence.

Et, selon l' homme page gettimeofday(), l'utilisation de la timezonestructure est obsolète, donc l' tzargument doit normalement être NULL, pour plus de détails veuillez consulter la page man.


1
> gettimeofday () pour spécifier le fuseau horaire, j'utilise NULL, qui ignore le fuseau horaire, mais vous pouvez spécifier un fuseau horaire si besoin. Vous avez tort. Le fuseau horaire doit être introduit exclusivement via un appel à localtime ().
vitaly.v.ch

@ vitaly.v.ch J'ai fait un test, en passant le tzparamètre gettimeofday()as &(struct timezone tz = {480, 0})n'obtiendra aucun avertissement, et cela n'a aucun effet sur le résultat, cela a du sens, car la longreprésentation du temps n'est pas pertinente ni affectée par fuseau horaire lui-même, non?
Eric Wang

Il n'y avait aucune raison de faire un test. Le noyau Linux n'a pas les informations appropriées sur les fuseaux horaires, et en même temps n'a pas de moyen de les fournir. C'est une raison pour laquelle l'argument tz est traité de manière très spécifique. une longue représentation n'a pas d'importance.
vitaly.v.ch

@ vitaly.v.ch À un moment donné, la représentation longue ne varie pas en raison du fuseau horaire, c'est pourquoi c'est important, et pour cette raison, seule NULLla valeur raisonnable à passer. Et je pense que les tests sont toujours une bonne approche pour prouver les choses.
Eric Wang



0

Dérivé de la réponse POSIX de Dan Moulding, cela devrait fonctionner:

#include <time.h>
#include <math.h>

long millis(){
    struct timespec _t;
    clock_gettime(CLOCK_REALTIME, &_t);
    return _t.tv_sec*1000 + lround(_t.tv_nsec/1.0e6);
}

Aussi comme le souligne David Guyon: compile avec -lm

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.