So drucken Sie die Zeit im Format: 2009‐08‐10 18: 17: 54.811


95

Was ist die beste Methode, um die Zeit in C im Format auszudrucken 2009‐08‐10 
18:17:54.811?

Antworten:


107

Verwenden Sie 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;
}

Schauen Sie sich diese Frage für Millisekunden an. Wie messe ich die Zeit in Millisekunden mit ANSI C?


Es ist jetzt eine noch bessere Antwort und bietet Tipps, wie Sie mit dem Millisekunden-Teil umgehen können. Ich denke, Ihr Puffer ist jetzt etwas länger als nötig.
Jack Kelly

14
Lieber länger als kürzer sein :-)
paxdiablo

Hervorragende Antwort. Ich konnte alle möglichen Dinge in PHP tun, wusste aber, dass es in C. THanks schon alles gab.
Vijay Kumar Kanta

1
Vielleicht sollte die Linie time(&timer)eher sein timer = time(NULL);, zumindest für 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
Die Antwort ist in mindestens einem Fall (Linux) definitiv falsch, da "struct tm", das von localtime () verwendet wird, keine Zeitinformationen unter den Sekunden enthält. Stattdessen hat "struct timeval", das von gettimeofday () verwendet wird, Mikrosekunden, die geteilt durch 1000 die Millisekunden ergeben. All diese Upvotes sind wirklich falsch und irreführend! Es sei denn, jemand meldet, unter welcher Architektur Sie mit "struct tm" Zeitdetails unterhalb der Sekunde erhalten.
EnzoR

30

Die obigen Antworten beantworten die Frage nicht vollständig (insbesondere den Millisekunden-Teil). Meine Lösung hierfür ist, gettimeofday vor strftime zu verwenden. Beachten Sie die Vorsicht, um zu vermeiden, dass Millisekunden auf "1000" gerundet werden. Dies basiert auf der Antwort von 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;
}

gettimeofdayist bei Windows-Implementierungen nicht verfügbar
Mendes

Bitte fügen Sie beim Erstellen '-lm'-Optionen hinzu.
Skysign

3
Ich denke, dass Puffer [24] genug ist, Grund ist wie unten, JJJJ: MM: TT HH: MM: SS.mmm + '\ 0', ist 24.
Skysign

@Mendes, warum Windows erwähnen? Die Frage betrifft die einfache C-Sprache. Dies ist eine bessere Antwort (wenn auch nicht die richtige), trotz all dieser falschen Gegenstimmen!
EnzoR

2
user3624334: Nein, Sie verstehen den Code nicht. Es gibt nur eine Anfrage nach Zeit. Ich nehme an, Sie meinen den Ortszeitaufruf - er formatiert nur die Ausgabe von gettimeofday neu.
Chris

12

time.hdefiniert eine strftimeFunktion, die Ihnen eine Textdarstellung einer time_tVerwendung von etwas geben kann wie:

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

Aber das gibt Ihnen keine Auflösung von weniger als einer Sekunde, da diese nicht von a erhältlich ist time_t. Es gibt aus:

2010-09-09 10:08:34.000

Wenn Sie durch die Spezifikationen wirklich eingeschränkt sind und den Abstand zwischen Tag und Stunde nicht möchten, entfernen Sie ihn einfach aus der Formatzeichenfolge.


+1 für den zweckmäßigen Trick zum Ausfüllen der Anzeige in Millisekunden. Ich hatte einmal einen Kunden, der wollte, dass ich das mache, aber mit Ziffern ungleich Null, so dass es so aussah, als gäbe es dort eine Bedeutung. Ich habe ihm davon abgeraten, aber zugestimmt, Nullen einzugeben.
RBerteig

4
Ein Freund von mir (natürlich nicht ich) hat einmal einen ähnlichen Trick angewendet - sie haben die Statik mit der letzten Sekunde und "Millisekunde" beibehalten. Wo sich die Sekunde seit dem letzten Mal nicht geändert hatte, fügten sie Millisekunden nur einen zufälligen Wert zwischen 1 und 200 hinzu (wobei sichergestellt wurde, dass er nicht über 999 hinausging - das tatsächliche Maximum für den Rand () war immer das Minimum von 200 und die halbe Entfernung bis 999). Wo sich die Sekunde geändert hat, haben sie Millisekunden vor dem Hinzufügen auf 0 gesetzt. Schöne scheinbar zufällige, aber richtig
geordnete

5

Der folgende Code wird mit Mikrosekundengenauigkeit gedruckt. Alles, was wir tun müssen, ist , den erstellten String zu verwenden gettimeofdayund strftimean ihn tv_secanzuhängen tv_usec.

#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

Sie könnten verwenden strftime, haben aber struct tmkeine Auflösung für Teile von Sekunden. Ich bin mir nicht sicher, ob dies für Ihre Zwecke unbedingt erforderlich ist.

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

Trick:

    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
Bitte erläutern Sie, warum dies funktioniert. und was genau los ist.
Raj Kamal

Trotzdem wie in den obigen Beispielen, aber nur effektiver. `time_len + = snprintf (log_buff + time_len, Größe von log_buff-time_len," log var is =% s ", logvar); int ret = write (log_fd, log_buff, time_len); `
Андрей Мельников

Woher importiere ich gettimeofday?
AndreyP

1

Keine der Lösungen auf dieser Seite hat für mich funktioniert. Ich habe sie verwechselt und mit Windows und Visual Studio 2019 kompatibel gemacht.

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

Ergebnis:

2020: 08: 02 06: 41: 59.107

2020: 08: 02 06: 41: 59.196

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.