Eine Möglichkeit, es zu formatieren, ist:
printf("%lld.%.9ld", (long long)ts.tv_sec, ts.tv_nsec);
Im Folgenden wird ein ISO8601- und RFC3339-konformer UTC-Zeitstempel zurückgegeben, einschließlich Nanosekunden.
Es verwendet strftime()
, was mit struct timespec
funktioniert genauso gut wie mit struct timeval
weil es nur auf die Anzahl der Sekunden ankommt, die beide liefern. Nanosekunden werden dann angehängt (Vorsicht mit Nullen auffüllen!) sowie das UTC-Suffix 'Z'.
Beispielausgabe:2021-01-19T04:50:01.435561072Z
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
int utc_system_timestamp(char[]);
int main(void) {
char buf[31];
utc_system_timestamp(buf);
printf("%s\n", buf);
}
// Allocate exactly 31 bytes for buf
int utc_system_timestamp(char buf[]) {
const int bufsize = 31;
const int tmpsize = 21;
struct timespec now;
struct tm tm;
int retval = clock_gettime(CLOCK_REALTIME, &now);
gmtime_r(&now.tv_sec, &tm);
strftime(buf, tmpsize, "%Y-%m-%dT%H:%M:%S.", &tm);
sprintf(buf + tmpsize -1, "%09luZ", now.tv_nsec);
return retval;
}
GCC-Befehlszeilenbeispiel (beachten Sie die -lrt
):
gcc foo.c -o foo -lrt
Ich wollte die gleiche Frage stellen. Hier ist meine aktuelle Lösung, um eine Zeichenfolge wie diese zu erhalten:2013-02-07 09:24:40.749355372
Ich bin mir nicht sicher, ob es eine einfachere Lösung als diese gibt, aber zumindest ist das String-Format mit diesem Ansatz frei konfigurierbar.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define NANO 1000000000L
// buf needs to store 30 characters
int timespec2str(char *buf, uint len, struct timespec *ts) {
int ret;
struct tm t;
tzset();
if (localtime_r(&(ts->tv_sec), &t) == NULL)
return 1;
ret = strftime(buf, len, "%F %T", &t);
if (ret == 0)
return 2;
len -= ret - 1;
ret = snprintf(&buf[strlen(buf)], len, ".%09ld", ts->tv_nsec);
if (ret >= len)
return 3;
return 0;
}
int main(int argc, char **argv) {
clockid_t clk_id = CLOCK_REALTIME;
const uint TIME_FMT = strlen("2012-12-31 12:59:59.123456789") + 1;
char timestr[TIME_FMT];
struct timespec ts, res;
clock_getres(clk_id, &res);
clock_gettime(clk_id, &ts);
if (timespec2str(timestr, sizeof(timestr), &ts) != 0) {
printf("timespec2str failed!\n");
return EXIT_FAILURE;
} else {
unsigned long resol = res.tv_sec * NANO + res.tv_nsec;
printf("CLOCK_REALTIME: res=%ld ns, time=%s\n", resol, timestr);
return EXIT_SUCCESS;
}
}
Ausgabe:
gcc mwe.c -lrt
$ ./a.out
CLOCK_REALTIME: res=1 ns, time=2013-02-07 13:41:17.994326501