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?

Dominic Bou-Samra
quelle

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?

Hamid Nazari
quelle
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;
}
Chris
quelle
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.

paxdiablo
quelle
+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;
}
Nataraj
quelle
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);
Jack Kelly
quelle
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);
Андрей Мельников
quelle
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

PinnedObject
quelle