Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 将结构timeval转换为可打印格式_C_Linux - Fatal编程技术网

C 将结构timeval转换为可打印格式

C 将结构timeval转换为可打印格式,c,linux,C,Linux,您能否帮助我如何将struct timeval实例格式化为人类可读的格式,如“2010-01-01 15:35:10.0001”使用localtime和strftime转换tv\u sec,然后附加tv\u usec部分。您可以使用该函数将日期和时间转换为字符串。您需要手动附加微秒部分,因为它不在()处理的struct tm中。下面是一个片段: struct timeval tv; time_t nowtime; struct tm *nowtm; char tmbuf[64], buf[64]

您能否帮助我如何将
struct timeval
实例格式化为人类可读的格式,如“2010-01-01 15:35:10.0001”

使用
localtime
strftime
转换
tv\u sec
,然后附加
tv\u usec
部分。

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

您需要手动附加微秒部分,因为它不在()处理的
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到999999,因此必须始终将其填充到6位。我们不想将例如57微秒误报为570000(比较“1.57”和“1.000057”)


我认为您正在寻找此代码,仅供参考。

结合以前的答案和注释,将格式更改为符合,并检查所有错误条件,您将得到以下结果:

#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;
}
#包括
#包括
ssize_t format_timeval(结构timeval*tv,字符*buf,大小sz)
{
ssize_t writed=-1;
struct tm*gm=gmtime(&tv->tv_-sec);
国际单项体育联合会(总经理)
{
书面=(ssize_t)标准时间(buf,sz,“%Y-%m-%dT%H:%m:%S”,gm);
如果((写入>0)和((写入的大小电视使用);
书面=(w>0)?书面+w:-1;
}
}
书面回报;
}
int main(){
结构时间值电视;
char-buf[28];
if(gettimeofday(&tv,NULL)!=0){
perror(“gettimeofday”);
返回1;
}
如果(格式_timeval(&tv,buf,sizeof(buf))>0){
printf(“%s\n”,buf);
//样本输出:
//2015-05-09T04:18:42.514551Z
}
返回0;
}
使用而不是本地时间转换电视秒,因为如果编写全局函数,可能会导致一些问题。 如果您的函数可以在多线程解决方案中工作,那么请考虑使用

< P>这就是我使用的:

#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;
}
#包括
#包括
#ifdef_WIN32
#定义WIN32_精益_和_平均值
#包括
#包括
#定义gmtime_r(ptime,ptm)(gmtime_s((ptm),(ptime)),(ptm))
#否则
#包括
#恩迪夫
#定义ISO8601_LEN(尺寸为“1970-01-01T23:59:59.123456Z”)
char*timeval_to_str(char iso8601[restrict static iso8601_LEN],无符号精度,const struct timeval*restrict tv){
struct-tm;
如果(!gmtime\u r(&tv->tv\u sec,&tm))
返回memcpy(iso8601,“错误:年溢出”,sizeof“错误:年溢出”);
tm.tm_年%=10*1000;
char*frac=iso8601+strftime(iso8601,尺寸为“1970-01-01T23:59:59.”,%Y-%m-%dT%H:%m:%SZ.”,&tm);
if(精度){
无符号长usecs=tv->tv\U usec;
对于(int i=精度;i<6;i++)usecs/=10;
字符*空格=frac+sprintf(frac-1,“.%-*luZ”,精度,usecs)-3;
if(空格>分形)while(*空格=“”)*空格--='0';
}
返回iso8601;
}

精度
指定秒分数的宽度。代码是y10k和yINT\u MAX-证明。

重复的?不是dup,因为这一个指定了人类可读的格式,指向stftime,而另一个只提取秒数和使用秒数。保存strftime的返回值(返回返回的字节数)可以更有效地完成此操作并使用它索引到同一个缓冲区中,然后可以将该缓冲区传递给snprintf。这将利用一个缓冲区并避免strftime()中字符串的额外副本。这对您的答案和整个线程都非常有用。作为补充,在最后一行中,也许最好指定
“,%s.%06ld”
。RegardsI收到一个警告:格式“%d”要求参数类型为“int”,但参数5在最后一行有类型为“\uu suseconds\u t{aka long int}”[-Wformat=]的参数来摆脱它?@bakalolo很好,我忘了它是
long
。修好了,谢谢!请注意,
ctime()
asctime()
返回的值的格式(例如“Wed Jun 30 21:49:08 1993\n”)与OP的要求不匹配,因为它们不包括小数秒,甚至没有最后的秒数,因此之后没有简单的方法附加小数秒。注意,我同意@JohnHascall的上述评论,这并不能解决上述问题。我将把答案留在这里,这样就不会有其他人想用这种方法来解决了。strftime将
struct tm
作为时间参数,而不是
struct timeval
#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;
}