Come stampare l'ora nel formato: 2009‐08-10 18:17: 54.811


96

Qual è il metodo migliore per stampare l'ora in C nel formato 2009‐08‐10 
18:17:54.811?

Risposte:


108

Usa strftime () .

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

int main()
{
    time_t timer;
    char buffer[26];
    struct tm* tm_info;

    timer = time(NULL);
    tm_info = localtime(&timer);

    strftime(buffer, 26, "%Y-%m-%d %H:%M:%S", tm_info);
    puts(buffer);

    return 0;
}

Per parte millisecondi, dai un'occhiata a questa domanda. Come misurare il tempo in millisecondi utilizzando ANSI C?


È una risposta ancora migliore ora e fornisce suggerimenti per cercare come gestire la parte del millisecondo. Penso che il tuo buffer ora sia un po 'più lungo di quanto dovrebbe essere, però.
Jack Kelly

14
Meglio essere più lunghi che brevi :-)
paxdiablo

Ottima risposta. Potevo fare ogni genere di cose in PHP, ma sapevo che era già tutto lì in C. Grazie.
Vijay Kumar Kanta

1
Forse la linea time(&timer)dovrebbe essere piuttosto timer = time(NULL);, almeno per Linux. The tloc argument is obsolescent and should always be NULL in new code. When tloc is NULL, the call cannot fail.
Antonin Décimo

5
La risposta è decisamente sbagliata in almeno un caso (Linux) poiché la "struct tm" usata da localtime () non contiene alcuna informazione temporale al di sotto dei secondi. Invece la "struct timeval" usata da gettimeofday () ha microsecondi che, divisi per 1000 restituiranno i millisecondi. Tutti questi voti positivi sono davvero sbagliati e fuorvianti! A meno che qualcuno non segnali sotto quale architettura si ottengono dettagli temporali sotto il secondo con "struct tm".
EnzoR

30

Le risposte di cui sopra non rispondono completamente alla domanda (in particolare la parte millisec). La mia soluzione è usare gettimeofday prima di strftime. Notare la cura per evitare di arrotondare millisec a "1000". Questo si basa sulla risposta di Hamid Nazari.

#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include <math.h>

int main() {
  char buffer[26];
  int millisec;
  struct tm* tm_info;
  struct timeval tv;

  gettimeofday(&tv, NULL);

  millisec = lrint(tv.tv_usec/1000.0); // Round to nearest millisec
  if (millisec>=1000) { // Allow for rounding up to nearest second
    millisec -=1000;
    tv.tv_sec++;
  }

  tm_info = localtime(&tv.tv_sec);

  strftime(buffer, 26, "%Y:%m:%d %H:%M:%S", tm_info);
  printf("%s.%03d\n", buffer, millisec);

  return 0;
}

gettimeofdaynon è disponibile su implementazioni Windows
Mendes

Si prega di aggiungere le opzioni "-lm" quando lo si crea.
skysign

3
Penso che il buffer [24] sia sufficiente, il motivo è come di seguito, AAAA: MM: GG HH: MM: SS.mmm + '\ 0', è 24.
skysign

@ Mendes, perché menzionare Windows? La domanda riguarda il linguaggio C semplice. Questa è una risposta migliore (anche se non quella giusta), nonostante tutti quei voti sbagliati!
EnzoR

2
user3624334: No, non capisci il codice. C'è solo una richiesta di tempo. Presumo che tu intenda la chiamata localtime - riformatta solo l'output di gettimeofday.
Chris

12

time.hdefinisce una strftimefunzione che può darti una rappresentazione testuale di un time_tusando qualcosa come:

#include <stdio.h>
#include <time.h>
int main (void) {
    char buff[100];
    time_t now = time (0);
    strftime (buff, 100, "%Y-%m-%d %H:%M:%S.000", localtime (&now));
    printf ("%s\n", buff);
    return 0;
}

ma questo non ti darà una risoluzione inferiore al secondo poiché non è disponibile da un file time_t. Emette:

2010-09-09 10:08:34.000

Se sei davvero vincolato dalle specifiche e non desideri lo spazio tra il giorno e l'ora, rimuovilo dalla stringa di formato.


+1 per l'espediente trucco per riempire il display al millisecondo. Una volta ho avuto un cliente che voleva che lo facessi, ma con cifre diverse da zero, quindi sembrava che ci fosse un significato lì. L'ho convinto a non farlo, ma ho accettato di mettere degli zeri.
RBerteig

4
Un mio amico (non io ovviamente) una volta ha usato un trucco simile: hanno mantenuto la statica contenente l'ultimo secondo e "millisecondi". Dove il secondo non era cambiato dall'ultima volta, hanno semplicemente aggiunto un valore casuale compreso tra 1 e 200 in millisec (assicurandosi che non andasse oltre 999, ovviamente - il massimo effettivo per rand () era sempre il minimo di 200 e metà della distanza a 999). Dove il secondo è cambiato, hanno semplicemente impostato millisec su 0 prima dell'aggiunta. Piacevoli millisecondi apparentemente casuali ma adeguatamente sequenziati e il cliente non era il più saggio :-)
paxdiablo

5

Il codice seguente viene stampato con una precisione al microsecondo. Tutto quello che dobbiamo fare è usare gettimeofdayand strftimeon tv_sece aggiungere tv_usecalla stringa costruita.

#include <stdio.h>
#include <time.h>
#include <sys/time.h>
int main(void) {
    struct timeval tmnow;
    struct tm *tm;
    char buf[30], usec_buf[6];
    gettimeofday(&tmnow, NULL);
    tm = localtime(&tmnow.tv_sec);
    strftime(buf,30,"%Y:%m:%dT%H:%M:%S", tm);
    strcat(buf,".");
    sprintf(usec_buf,"%dZ",(int)tmnow.tv_usec);
    strcat(buf,usec_buf);
    printf("%s",buf);
    return 0;
}

2

Potresti usare strftime, ma struct tmnon ha risoluzione per parti di secondi. Non sono sicuro che sia assolutamente necessario per i tuoi scopi.

struct tm tm;
/* Set tm to the correct time */
char s[20]; /* strlen("2009-08-10 18:17:54") + 1 */
strftime(s, 20, "%F %H:%M:%S", &tm);

2

trucco:

    int time_len = 0, n;
    struct tm *tm_info;
    struct timeval tv;

    gettimeofday(&tv, NULL);
    tm_info = localtime(&tv.tv_sec);
    time_len+=strftime(log_buff, sizeof log_buff, "%y%m%d %H:%M:%S", tm_info);
    time_len+=snprintf(log_buff+time_len,sizeof log_buff-time_len,".%03ld ",tv.tv_usec/1000);

1
Si prega di spiegare perché funziona. e cosa sta succedendo esattamente.
Raj Kamal

Uguale agli esempi precedenti, ma solo in modo più efficace. `time_len + = snprintf (log_buff + time_len, sizeof log_buff-time_len," log var is =% s ", logvar); int ret = write (log_fd, log_buff, time_len); `
Андрей Мельников

Da dove si importa gettimeofday?
AndreyP,

1

Nessuna delle soluzioni in questa pagina ha funzionato per me, le ho mescolate e le ho fatte funzionare con Windows e Visual Studio 2019, ecco come:

#include <Windows.h>
#include <time.h> 
#include <chrono>

static int gettimeofday(struct timeval* tp, struct timezone* tzp) {
    namespace sc = std::chrono;
    sc::system_clock::duration d = sc::system_clock::now().time_since_epoch();
    sc::seconds s = sc::duration_cast<sc::seconds>(d);
    tp->tv_sec = s.count();
    tp->tv_usec = sc::duration_cast<sc::microseconds>(d - s).count();
    return 0;
}

static char* getFormattedTime() {
    static char buffer[26];

    // For Miliseconds
    int millisec;
    struct tm* tm_info;
    struct timeval tv;

    // For Time
    time_t rawtime;
    struct tm* timeinfo;

    gettimeofday(&tv, NULL);

    millisec = lrint(tv.tv_usec / 1000.0);
    if (millisec >= 1000) 
    {
        millisec -= 1000;
        tv.tv_sec++;
    }

    time(&rawtime);
    timeinfo = localtime(&rawtime);

    strftime(buffer, 26, "%Y:%m:%d %H:%M:%S", timeinfo);
    sprintf_s(buffer, 26, "%s.%03d", buffer, millisec);

    return buffer;
}

Risultato:

2020: 08: 02 06: 41: 59.107

2020: 08: 02 06: 41: 59.196

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.