What\'s the best method to print out time in C in the format 2009‐08‐10
18:17:54.811
?
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;
}
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.
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);
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
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;
}