Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Struct timeval to printable format

Tags:

c

linux

Could you please help me how to format a struct timeval instance to human readable format like "2010-01-01 15:35:10.0001"?

like image 274
marxin Avatar asked Mar 09 '10 12:03

marxin


3 Answers

You need to manually append the microseconds part, since it's not in the struct tm that strftime() deals with. Here's a snippet:

struct timeval tv;
time_t nowtime;
struct tm *nowtm;
char tmbuf[64], buf[64];

gettimeofday(&tv, NULL);
nowtime = tv.tv_sec;
nowtm = localtime(&nowtime);
strftime(tmbuf, sizeof tmbuf, "%Y-%m-%d %H:%M:%S", nowtm);
snprintf(buf, sizeof buf, "%s.%06ld", tmbuf, tv.tv_usec);

Note how we use explicit precision of 06 to get a zero-filled microseconds field. Since the microseconds go from 0 to 999,999, it must always be padded to 6 digits. We don't want to misrepresent e.g. 57 microseconds as 570,000 (compare "1.57" vs "1.000057").

like image 146
unwind Avatar answered Nov 09 '22 18:11

unwind


Convert the tv_sec using localtime, and strftime, then append tv_usec part.

like image 14
Didier Trosset Avatar answered Nov 09 '22 17:11

Didier Trosset


Combining previous answers and comments, changing the format to be RFC3339-compliant, and checking all of the error conditions, you get this:

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

ssize_t format_timeval(struct timeval *tv, char *buf, size_t sz)
{
  ssize_t written = -1;
  struct tm *gm = gmtime(&tv->tv_sec);

  if (gm)
  {
    written = (ssize_t)strftime(buf, sz, "%Y-%m-%dT%H:%M:%S", gm);
    if ((written > 0) && ((size_t)written < sz))
    {
      int w = snprintf(buf+written, sz-(size_t)written, ".%06dZ", tv->tv_usec);
      written = (w > 0) ? written + w : -1;
    }
  }
  return written;
}

int main() {
  struct timeval tv;
  char buf[28];
  if (gettimeofday(&tv, NULL) != 0) {
    perror("gettimeofday");
    return 1;
  }
  if (format_timeval(&tv, buf, sizeof(buf)) > 0) {
    printf("%s\n", buf);
    // sample output:
    // 2015-05-09T04:18:42.514551Z
  }
  return 0;
}
like image 5
Joe Hildebrand Avatar answered Nov 09 '22 17:11

Joe Hildebrand