前言:

之前一篇博文对 time.h 进行了解读,但是如果需要时间精确到毫秒,time_t、tm还是无法满足的,需要另外一种方式。

 

方法1:timespec和timeval

#include <time.h>


struct timespec
{
    __time_t tv_sec;        /* Seconds.  */
    __syscall_slong_t tv_nsec;  /* Nanoseconds.  */
}

time.h 中有结构体timespec,这里精确到ns

 

#include <sys/time.h>


struct timeval
{
    __time_t tv_sec;        /* Seconds.  */
    __suseconds_t tv_usec;  /* Microseconds.  */
}

sys/time.h 中结构体timeval 精确到us

比较下来,timespec 和timeval 只是在第二个成员存在一个1000的数量级只差。即 tv_nsec = tv_usec *1000;

 

我们这里采用sys/time.h 中现成的接口:

void sysUsecTime(void)
{
    struct timeval tv;
    struct timezone tz;   
    struct tm *t;
     
    gettimeofday(&tv, &tz);
    printf("tv_sec:%ld\n",tv.tv_sec);
    printf("tv_usec:%ld\n",tv.tv_usec);
    printf("tz_minuteswest:%d\n",tz.tz_minuteswest);
    printf("tz_dsttime:%d\n",tz.tz_dsttime);
     
    t = localtime(&tv.tv_sec);
    printf("time_now:%d-%d-%d %d:%d:%d.%ld\n", 1900+t->tm_year, 1+t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec);
}

使用gettimeofday接口,获取精确的秒时间和毫秒时间。

可以通过tv_sec,获取精确的tm 数据;通过tv_usec 获取精确的ms 数据。

如果不需要获取时区相关信息,第二个参数可以设为NULL。

 

时区结构:

#include <sys/time.h>

struct timezone
{
    int tz_minuteswest; /* Minutes west of GMT.  */
    int tz_dsttime;     /* Nonzero if DST is ever in effect.  */
};

 

方法2:timeb

#include <sys/timeb.h>

struct timeb
{
    time_t time;
    unsigned short int millitm;
    short int timezone;
    short int dstflag;
};

extern int ftime (struct timeb *__timebuf);

没有看到源码中对于timeb 的其他解释,应该是time.h的补充?

通过ftime 函数可以直接获取到timeb 信息,其中millitm 为毫秒。

 

实例:

void sysUsecTime4(void)
{
    printf("====sysUsecTime4\n");
    struct timeb tv;
    struct tm *t;
     
    ftime(&tv);
     
    t = localtime(&tv.time);
    printf("time_now:%d-%d-%d %d:%d:%d.%ld\n", 1900+t->tm_year, 1+t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, tv.millitm);
}

 

遗留问题:

这里写下个人项目中碰到的疑点,使用同样的程序,将其中的获取时间这一块的代码使用timeval 和timeb,timeval打印出来的log 时间居然不正确,这个不明白是为什么?

使用timeval:

01-04 07:23:32.947 JA310-1881 user.info shift: [271 | 285]: Element::bufferReturned: buf id=21, element id=2
01-04 07:23:32.948 JA310-1881 user.info shift: [271 | 285]: BufferGroup::returnBuffer: buf id=21
01-04 07:23:32.949 JA310-1881 user.info shift: [271 | 285]: StreamFlow::releaseCallbackBuffer: done
01-04 07:23:32.949 JA310-1881 user.info JMF-Media: [1186 | 1188]: releaseBuffer id = [21], ret = [0] 
01-04 07:23:32.113 JA310-1881 user.info shift: [271 | 1207]: MediaFileReader::threadLoop end mLoopInterval(66666)
01-04 07:23:32.113 JA310-1881 user.info shift: [271 | 1207]: Element::bufferReturned: buf id=4, element id=1
01-04 07:23:32.113 JA310-1881 user.info shift: [271 | 1207]: MediaFileReader::returnBuffer, buf id=4
01-04 07:23:32.113 JA310-1881 user.info shift: [271 | 1207]: BufferGroup::returnBuffer: buf id=4
01-04 07:23:32.113 JA310-1881 user.info shift: [271 | 1207]: MediaFileReader::threadLoop

注意第四行和第五行,不知道什么鬼,时间会从949变成113。

 

而使用timeb 打印之后的log 时间是正常的。

 

 

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐