在Linux中通过C语言获取当前系统时间,精确到毫秒或微秒

        结构体tm的定义如下:

struct tm
{
int tm_sec;/* Seconds.[0-60] (1 leap second) */
int tm_min;/* Minutes.[0-59] */
int tm_hour;/* Hours.[0-23] */
int tm_mday;/* Day.[1-31] */
int tm_mon;/* Month.[0-11] */
int tm_year;/* Year- 1900. */
int tm_wday;/* Day of week.[0-6] */
int tm_yday;/* Days in year.[0-365]*/
int tm_isdst;/* DST.[-1/0/1]*/
#ifdef__USE_BSD
long int tm_gmtoff;/* Seconds east of UTC. */
__const char *tm_zone;/* Timezone abbreviation. */
#else
long int __tm_gmtoff;/* Seconds east of UTC. */
__const char *__tm_zone;/* Timezone abbreviation. */
#endif
};

        使用它需要包含Linux的默认头文件存储路径/usr/include中的头文件time.h,但是它只能精确到秒。

        系统还为我们定义了另一些和时间相关的头文件,在一个叫sys的子目录中。该目录的位置和系统有一定关系。比如我用的Ubuntu 20.04.4 LTS,该子目录位置:/usr/include/x86_64-linux-gnu/sys。在这个目录中的头文件timeb.h中定义了结构体timeb:

struct timeb
{
    time_t time;                /* Seconds since epoch, as from `time'.  */
    unsigned short int millitm;    /* Additional milliseconds.  */
    short int timezone;         /* Minutes west of GMT.  */
    short int dstflag;          /* Nonzero if Daylight Savings Time used.  */
};

        其中的成员变量time为从Epoch到创建struct timeb时经历的秒数,millitm为附加的毫秒数。利用这个结构体,就可以获取到精确到毫秒的时间了。

        头文件timeb.h中还声明了函数ftime:      

extern int ftime (struct timeb *__timebuf) __nonnull ((1)) __attribute_deprecated__;

        此函数的参数是结构体timeb的指针,调用此函数就会将获取到的时间,包含秒数和毫秒数放到参数变量中。

        然后需要将获取到的秒数转成时间格式,需要调用函数localtime。此函数在头文件time.h中声明:

/* Return the `struct tm' representation
of *TIMER in the local timezone.  */
extern struct tm *localtime (const time_t *__timer) __THROW;

        因此,我们需要将获取到的秒数的指针传给localtime(),该函数返回指向结构体tm的指针。将结构体tm的成员变量按照格式输出就可以了。        

        代码如下:

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

int main(void)
{
    struct timeb tTimeB;
    ftime(&tTimeB);//获取当前的秒数和毫秒数
    struct tm *tTM = localtime(&tTimeB.time);//将秒数转为时间格式
    printf("%04d-%02d-%02d %02d:%02d:%02d.%03d\n", tTM->tm_year + 1900, 
    tTM->tm_mon + 1, tTM->tm_mday, tTM->tm_hour, tTM->tm_min, tTM->tm_sec, 
    tTimeB.millitm);

    return 0;
}

        编译会有警告,ftime函数不推荐使用,不过并不影响编译和运行:

        如果要进一步精确到微秒需要使用结构体timeval,使用它需要包含头文件sys/time.h:

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

        成员变量tv_sec是从Epoch到创建struct timeval时经历的秒数,tv_usec是额外的微秒数。

        获取当前时间(秒数和微秒数)需要调用函数gettimeofday,该函数也是在sys/time.h中声明:

/* Get the current time of day, putting it into *TV.
   If TZ is not null, *TZ must be a struct timezone, and both fields
   will be set to zero.
   Calling this function with a non-null TZ is obsolete;
   use localtime etc. instead.
   This function itself is semi-obsolete;
   most callers should use time or clock_gettime instead. */
extern int gettimeofday (struct timeval *__restrict __tv,
                         void *__restrict __tz) __THROW __nonnull ((1));

        此函数有两个参数,第一个是结构体timeval的指针,第二个参数表示时区,如果不需要获取可以传NULL。调用它之后就可以获取到当前时间的秒数和额外的微秒数。

        然后同样调用localtime函数将秒数转成时间格式。我们想输出的格式是:年-月-日 时:分:秒.毫秒.微秒,因此将tv_usec / 1000就是毫秒值,将tv_usec % 1000就是剩余的微秒值。代码如下:

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

int main(void)
{
        struct timeval tTimeVal;
        gettimeofday(&tTimeVal, NULL);
        struct tm *tTM = localtime(&tTimeVal.tv_sec);
        printf("%04d-%02d-%02d %02d:%02d:%02d.%03ld.%03ld\n", 
        tTM->tm_year + 1900, tTM->tm_mon + 1, tTM->tm_mday, 
        tTM->tm_hour, tTM->tm_min, tTM->tm_sec,             
        tTimeVal.tv_usec / 1000, tTimeVal.tv_usec % 1000);

        return 0;
}

编译运行:

参考资料:

1、linux timeb 结构体,Linux time函数:https://blog.csdn.net/weixin_39867200/article/details/116927426

2、struct timeval结构体:https://blog.csdn.net/lizhengze1117/article/details/103313928

  • 3
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值