您能否帮我解决一下如何将struct timeval
实例格式化为人类可读的格式,例如“2010-01-01 15:35:10.0001”?
答案 0 :(得分:63)
您需要手动附加微秒部分,因为它不在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”)。
答案 1 :(得分:13)
使用tv_sec
和localtime
转换strftime
,然后追加tv_usec
部分。
答案 2 :(得分:3)
ctime((const time_t *) &timeval.ts.tv_sec)
我认为您正在寻找此代码,仅供参考。
答案 3 :(得分:2)
将先前的答案和评论结合起来,将格式更改为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;
}
答案 4 :(得分:1)
您可以使用strftime功能将日期和时间转换为字符串。
答案 5 :(得分:1)
使用localtime_s而不是localtime转换tv_sec,因为如果您正在编写全局函数,则可能会导致一些问题。 如果您的函数可以在多线程解决方案中工作,那么请考虑使用localtime_r
答案 6 :(得分:1)
这就是我使用的:
#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
- 证明。