如何打印时间格式: 2009-08-1018:17:54.811

2009‐08‐10 
18:17:54.811格式用 C 打印时间的最佳方法是什么?

244979 次浏览

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

For milliseconds part, have a look at this question. How to measure time in milliseconds using ANSI C?

You could use strftime, but struct tm doesn't have resolution for parts of seconds. I'm not sure if that's absolutely required for your purposes.

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);

time.h defines a strftime function which can give you a textual representation of a time_t using something like:

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

but that won't give you sub-second resolution since that's not available from a time_t. It outputs:

2010-09-09 10:08:34.000

If you're really constrained by the specs and do not want the space between the day and hour, just remove it from the format string.

The above answers do not fully answer the question (specifically the millisec part). My solution to this is to use gettimeofday before strftime. Note the care to avoid rounding millisec to "1000". This is based on Hamid Nazari's answer.

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

Following code prints with microsecond precision. All we have to do is use gettimeofday and strftime on tv_sec and append tv_usec to the constructed string.

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

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);

None of the solutions on this page worked for me, I mixed them up and made them working with Windows and Visual Studio 2019, Here's How :

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


Result :

2020:08:02 06:41:59.107

2020:08:02 06:41:59.196