将timeval结构化为可打印的格式

你能帮我如何格式struct timeval实例像人类可读的格式,如“2010-01-01 15:35:10.0001”?

Solutions Collecting From Web of "将timeval结构化为可打印的格式"

使用localtimestrftime转换tv_sec ,然后附加tv_usec部分。

您需要手动附加微秒部分,因为它不在strftime ()处理的struct tm中。 这是一个片段:

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

注意我们如何使用06显式精度来获得一个零填充的微秒字段。 由于微秒从0到999,999,它必须始终填充到6位数。 我们不想歪曲57毫秒为570,000(比较“1.57”和“1.000057”)。

 ctime((const time_t *) &timeval.ts.tv_sec) 

我想你正在寻找这个代码,仅供参考。

您可以使用strftime函数将日期和时间转换为字符串。

结合以前的答案和评论,改变格式为RFC3339兼容,并检查所有的错误条件,你会得到这个:

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

使用localtime_s而不是本地时间来转换tv_sec,因为如果您正在编写全局函数,则可能会导致一些问题。 如果你的函数可能在多线程解决方案中工作,那么请考虑使用localtime_r

这是我使用的:

 #include <time.h> #include <string.h> #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <winsock2.h> #define gmtime_r(ptime,ptm) (gmtime_s((ptm),(ptime)), (ptm)) #else #include <sys/time.h> #endif #define ISO8601_LEN (sizeof "1970-01-01T23:59:59.123456Z") char *timeval_to_str(char iso8601[restrict static ISO8601_LEN], unsigned precision, const struct timeval * restrict tv) { struct tm tm; if (!gmtime_r(&tv->tv_sec, &tm)) return memcpy(iso8601, "Error: Year overflow", sizeof "Error: Year overflow"); tm.tm_year %= 10*1000; char *frac = iso8601 + strftime(iso8601, sizeof "1970-01-01T23:59:59.", "%Y-%m-%dT%H:%M:%SZ", &tm); if (precision) { unsigned long usecs = tv->tv_usec; for (int i = precision; i < 6; i++) usecs /= 10; char *spaces = frac + sprintf(frac - 1, ".%-*luZ", precision, usecs) - 3; if (spaces > frac) while (*spaces == ' ') *spaces-- = '0'; } return iso8601; } 

precision指定秒分数的宽度。 代码是y10k和y INT_MAX