GNU/Linux >> Linux Esercitazione >  >> Linux

Formattazione struct timespec

Un modo per formattarlo è:

printf("%lld.%.9ld", (long long)ts.tv_sec, ts.tv_nsec);

Quanto segue restituirà un timestamp UTC conforme a ISO8601 e RFC3339, compresi i nanosecondi.

Utilizza strftime() , che funziona con struct timespec proprio come con struct timeval perché tutto ciò che interessa è il numero di secondi, che entrambi forniscono. Vengono quindi aggiunti i nanosecondi (attenzione a riempire con zeri!) e il suffisso UTC 'Z'.

Esempio di output: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;
}

Esempio di riga di comando GCC (notare il -lrt ):

gcc foo.c -o foo -lrt

Volevo fare la stessa domanda. Ecco la mia attuale soluzione per ottenere una stringa come questa:2013-02-07 09:24:40.749355372 Non sono sicuro che esista una soluzione più semplice di questa, ma almeno il formato della stringa è liberamente configurabile con questo approccio.

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

uscita:

gcc mwe.c -lrt 
$ ./a.out 
CLOCK_REALTIME: res=1 ns, time=2013-02-07 13:41:17.994326501

Linux
  1. Formattazione dei nomi nell'installazione di Hadoop?

  2. Come rilevare la modifica dell'indirizzo IP a livello di codice in Linux?

  3. API Linux per elencare i processi in esecuzione?

  4. Ottenere la larghezza del terminale in C?

  5. Limitazione dell'accesso alle chiamate di sistema per un'applicazione Linux

Trucchi di formattazione per il comando data di Linux

Valori massimi per time_t (struct timespec)

struct errore incompleto di sigazione

Converti millisecondi in timespec per la porta GNU

Come usare le variabili atomiche in C?

Come passare i parametri alla chiamata di sistema Linux?