Wie bekomme ich die aktuelle Uhrzeit in Millisekunden von C in Linux?

Lesezeit: 5 Minuten

Benutzeravatar von LLL
LLL

Wie erhalte ich die aktuelle Uhrzeit unter Linux in Millisekunden?

Benutzeravatar von Dan Moulding
Dan Formen

Dies kann mit der erreicht werden Posix clock_gettime Funktion.

In der aktuellen Version von POSIX gettimeofday ist veraltet markiert. Dies bedeutet, dass es möglicherweise aus einer zukünftigen Version der Spezifikation entfernt wird. Verfasser von Bewerbungen werden ermutigt, die zu verwenden clock_gettime Funktion statt gettimeofday.

Hier ist ein Beispiel für die Verwendung 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);
}

Wenn es Ihr Ziel ist, die verstrichene Zeit zu messen, und Ihr System die Option „monotone Uhr“ unterstützt, sollten Sie dies in Betracht ziehen CLOCK_MONOTONIC Anstatt von CLOCK_REALTIME.

  • +1, weil Sie POSIXly korrekt sind – aber Ihre Antwort hat die falschen Einheiten. Das OP will die Zeit nicht mit Millisekunden, sondern die Zeit in Millisekunden.

    – Pilkrähe

    28. Juni 2013 um 19:50 Uhr

  • Gute Lösung, aber nicht vergessen -lm in deiner gcc Befehl.

    – David Guyon

    2. Juni 2014 um 8:58 Uhr

  • Laut der Manpage für Round möchten Sie lround verwenden, wenn Sie das Ergebnis einer Ganzzahl (oder Long) zuweisen.

    – Hildred

    21. März 2016 um 21:42 Uhr

  • Sie müssen floor() anstelle von round() verwenden, damit nie auf 1000 ms aufgerundet wird. Andernfalls müssten Sie erhöhen s wenn das passiert. Wahrscheinlich ein seltenes Ereignis, aber die zusätzliche Ziffer kann Probleme verursachen.

    – Mike

    27. Dezember 2017 um 0:55 Uhr

  • @Mike Schöner Fang. Bei einem von zweitausend ist es nicht einmal so selten, sollte also definitiv behoben werden. Anstatt den Boden zu verwenden, würde ich es vorziehen, ein wenig mehr Genauigkeit beizubehalten und weiter zu runden, aber den zweiten Zähler erhöhen, wenn er auf 1000 aufrundet.

    – Dan Formen

    27. Dezember 2017 um 20:11 Uhr

Benutzeravatar von Yadab
Yadab

Sie müssen so etwas tun:

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

Benutzeravatar von Eric
Erich

Es folgt die util-Funktion, um den aktuellen Zeitstempel in Millisekunden abzurufen:

#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;
}

Über die Zeitzone:

gettimeofday() Unterstützung zur Angabe der Zeitzone verwende ich NULLdie die Zeitzone ignorieren, aber Sie können bei Bedarf eine Zeitzone angeben.


@Update – Zeitzone

Seit der long Die Darstellung der Zeit ist für die Zeitzone selbst nicht relevant oder wird von ihr beeinflusst, also die Einstellung tz param von gettimeofday() ist nicht notwendig, da es keinen Unterschied macht.

Und gem Mann Seite von gettimeofday()die Verwendung der timezone Struktur ist veraltet, daher die tz Das Argument sollte normalerweise als NULL angegeben werden, für Details lesen Sie bitte die Manpage.

  • > Unterstützung von gettimeofday() zur Angabe der Zeitzone, ich verwende NULL, wodurch die Zeitzone ignoriert wird, aber Sie können bei Bedarf eine Zeitzone angeben. Sie liegen falsch. Die Zeitzone sollte ausschließlich über den Aufruf von localtime() eingeführt werden.

    – vitaly.v.ch

    4. November 2017 um 2:55 Uhr

  • @vitaly.v.ch Ich habe eine Prüfung gemacht, die ich bestanden habe tz Parameter von gettimeofday() wie &(struct timezone tz = {480, 0}) wird keine Warnung bekommen, und es hat keinen Einfluss auf das Ergebnis, das macht Sinn, da die long Die Darstellung der Zeit ist für die Zeitzone selbst nicht relevant oder wird von ihr beeinflusst, oder?

    – Erich

    5. November 2017 um 6:33 Uhr

  • Es gab keinen Grund, irgendwelche Tests zu machen. Der Linux-Kernel hat keine richtigen Informationen über Zeitzonen und gleichzeitig keine Möglichkeit, diese bereitzustellen. Dies ist ein Grund, warum das tz-Argument auf sehr spezifische Weise verarbeitet wird. lange Darstellung spielt keine Rolle.

    – vitaly.v.ch

    5. November 2017 um 10:54 Uhr

  • @vitaly.v.ch Zu einem bestimmten Zeitpunkt variieren lange Repräsentationen nicht aufgrund der Zeitzone, deshalb ist es wichtig, und deshalb normalerweise nur NULL ist der angemessene Wert für die Übergabe. Und ich glaube, dass Testen immer ein guter Ansatz ist, um Dinge zu beweisen.

    – Erich

    5. November 2017 um 12:28 Uhr


Verwenden gettimeofday() um die Zeit in Sekunden und Mikrosekunden zu erhalten. Das Kombinieren und Runden auf Millisekunden bleibt als Übung übrig.

Ciro Santilli Benutzeravatar von OurBigBook.com
Ciro Santilli OurBigBook.com

C11 timespec_get

Es gibt bis zu Nanosekunden zurück, gerundet auf die Auflösung der Implementierung.

Es ist bereits in Ubuntu 15.10 implementiert. Die API sieht genauso aus wie die POSIX clock_gettime.

#include <time.h>
struct timespec ts;
timespec_get(&ts, TIME_UTC);
struct timespec {
    time_t   tv_sec;        /* seconds */
    long     tv_nsec;       /* nanoseconds */
};

Weitere Details hier: https://stackoverflow.com/a/36095407/895245

Diese Version benötigt keine Mathematikbibliothek und überprüft den Rückgabewert von clock_gettime().

#include <time.h>
#include <stdlib.h>
#include <stdint.h>

/**
 * @return milliseconds
 */
uint64_t get_now_time() {
  struct timespec spec;
  if (clock_gettime(1, &spec) == -1) { /* 1 is CLOCK_MONOTONIC */
    abort();
  }

  return spec.tv_sec * 1000 + spec.tv_nsec / 1e6;
}

Abgeleitet von Dan Mouldings POSIX-Antwort sollte dies funktionieren:

#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/1e6);
}

Auch wie von David Guyon hervorgehoben: kompilieren Sie mit -lm

  • Es besteht keine Notwendigkeit, Fließkommazahlen aufzurufen. Addieren Sie einfach 500K und teilen Sie die ganze Zahl durch 1M.

    – Kevin Thibedeau

    31. Oktober 2021 um 18:54 Uhr

  • Danke für den Tipp, habe meine Antwort korrigiert.

    – Jirka Justra

    1. November 2021 um 20:37 Uhr

1421150cookie-checkWie bekomme ich die aktuelle Uhrzeit in Millisekunden von C in Linux?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy