Linux C语言时间相关知识总结

2023-05-09 10:35:28 来源:Linux大陆

大家好,我是LinuxZn。

实际开发中,经常要获取各种时间。下面汇总几个常用的时间接口:


(资料图片)

1、clock_gettime

#include/***@brief根据系统时钟的类型,获取当前时间**Detailedfunctiondescription**@param[in]__clock_id:系统时钟的类型。常用取值:-CLOCK_REALTIME:从1970年1月1日到目前的时间-CLOCK_MONOTONIC:系统启动时间-CLOCK_PROCESS_CPUTIME_ID:本进程运行时间-CLOCK_THREAD_CPUTIME_ID:本线程运行的时间*@param[out]__tp:存放当前的时间。**@return成功则返回0,失败则返回-1*/intclock_gettime(clockid_t__clock_id,structtimespec*__tp);

timespec结构体:

structtimespec{__time_ttv_sec;/*Seconds.秒*/__syscall_slong_ttv_nsec;/*Nanoseconds.纳秒*/};

例子:

#include#include#includelonglongget_clock_sys_time_ns(void){structtimespectp;longlongtime_ns=0;clock_gettime(CLOCK_MONOTONIC,&tp);time_ns=(longlong)tp.tv_sec*1000000000+tp.tv_nsec;returntime_ns;}intmain(void){structtimespectp;///<获取从1970年1月1日到目前的时间memset(&tp,0,sizeof(structtimespec));clock_gettime(CLOCK_REALTIME,&tp);printf("clock_id=CLOCK_REALTIME,sec=%ld,nsec=%ld",tp.tv_sec,tp.tv_nsec);///<获取系统启动时间memset(&tp,0,sizeof(structtimespec));clock_gettime(CLOCK_MONOTONIC,&tp);printf("clock_id=CLOCK_MONOTONIC,sec=%ld,nsec=%ld,sys_time=%lldns",tp.tv_sec,tp.tv_nsec,get_clock_sys_time_ns());///<获取本进程运行时间memset(&tp,0,sizeof(structtimespec));clock_gettime(CLOCK_PROCESS_CPUTIME_ID,&tp);printf("clock_id=CLOCK_PROCESS_CPUTIME_ID,sec=%ld,nsec=%ld",tp.tv_sec,tp.tv_nsec);///<获取本线程运行时间memset(&tp,0,sizeof(structtimespec));clock_gettime(CLOCK_THREAD_CPUTIME_ID,&tp);printf("clock_id=CLOCK_THREAD_CPUTIME_ID,sec=%ld,nsec=%ld",tp.tv_sec,tp.tv_nsec);return0;}

编译、运行:

2、gettimeofday

#include/***@brief获取当前时间(从1970年1月1日到目前的时间)**Detailedfunctiondescription**@param[out]tv:当前UTC时间*@param[out]tz:当前时区信息**@return成功则返回0,失败则返回-1*/intgettimeofday(structtimeval*tv,structtimezone*tz);

timeval结构体:

structtimeval{__time_ttv_sec;/*Seconds.秒*/__suseconds_ttv_usec;/*Microseconds.微秒*/};

timezone结构体:

structtimezone{inttz_minuteswest;/*MinuteswestofGMT.和Greenwich时间差了多少分钟*/inttz_dsttime;/*NonzeroifDSTiseverineffect.日光节约时间的状态*/};

例子:

#include#include#includelonglongget_sys_time_ms(void){longlongtime_ms=0;structtimevaltv;gettimeofday(&tv,NULL);time_ms=((longlong)tv.tv_sec*1000000+tv.tv_usec)/1000;returntime_ms;}intmain(void){///<获取系统时间printf("sys_time=%lldms",get_sys_time_ms());return0;}

编译、运行:

3、time

#include/***@brief获取1970-01-010000+0000至今的秒数(UTC)**Detailedfunctiondescription**@param[out]tloc:返回的秒存储指针**@return成功则返回秒数,失败则返回-1,错误原因存在errno中。*/time_ttime(time_t*tloc);

time_t的类型:

typedeflongtime_t;

例子:

#include#includetime_tget_utc_time(void){returntime(NULL);}intmain(intargc,char**argv){time_tutc_time=get_utc_time();printf("utc_time=%lds",utc_time);return0;}

编译、运行:

4、localtime

#include/***@brief将time_t类型的时间转换为structtm类型的时间**Detailedfunctiondescription**@param[in]timep:当前UTC秒数**@return返回当地时间*/structtm*localtime(consttime_t*timep);

tm结构体:

structtm{inttm_sec;/*Seconds.[0-60](1leapsecond)*/inttm_min;/*Minutes.[0-59]*/inttm_hour;/*Hours.[0-23]*/inttm_mday;/*Day.[1-31]*/inttm_mon;/*Month.[0-11]注意:0代表1月,以此类推*/inttm_year;/*Year-1900.该值为实际年份减去1900*/inttm_wday;/*Dayofweek.[0-6]注意:0代表星期一,以此类推*/inttm_yday;/*Daysinyear.[0-365]从每年的1月1日开始的天数,其中0代表1月1日,以此类推*/inttm_isdst;/*DST.[-1/0/1]夏玲时标识符*/};

例子:

#include#includetime_tget_utc_time(void){returntime(NULL);}intmain(intargc,char**argv){time_tutc_time=get_utc_time();printf("utc_time=%lds",utc_time);structtm*local_tm=localtime(&utc_time);printf("localtime=%.4d-%.2d-%.2d%.2d:%.2d:%.2d",local_tm->tm_year+1900,local_tm->tm_mon+1,local_tm->tm_mday,local_tm->tm_hour,local_tm->tm_min,local_tm->tm_sec);return0;}

编译、运行:

5、localtime_r

#include/***@brief将time_t类型的时间转换为structtm类型的时间**Detailedfunctiondescription**@param[in]timep:当前UTC秒数*@param[out]timep:当地时间**@return返回当地时间*/structtm*localtime_r(consttime_t*timep,structtm*result);

localtime不是一个线程安全的函数,关于线程安全的知识点,看阅读往期文章:如何理解线程安全?。

对于实时性要求较高的系统,多个线程同时调用localtime,可能会造成数据被覆盖。我们项目中之前是用localtime来获取系统时间、日期。并使用这个数据去做逻辑,数据异常导致了逻辑异常。

后面使用localtime_r来替代,问题解决。

例子:

#include#includetime_tget_utc_time(void){returntime(NULL);}intmain(intargc,char**argv){time_tutc_time=get_utc_time();printf("utc_time=%lds",utc_time);structtmresult;structtm*local_tm=localtime_r(&utc_time,&result);printf("localtime=%.4d-%.2d-%.2d%.2d:%.2d:%.2d",local_tm->tm_year+1900,local_tm->tm_mon+1,local_tm->tm_mday,local_tm->tm_hour,local_tm->tm_min,local_tm->tm_sec);printf("resulttime=%.4d-%.2d-%.2d%.2d:%.2d:%.2d",result.tm_year+1900,result.tm_mon+1,result.tm_mday,result.tm_hour,result.tm_min,result.tm_sec);return0;}

编译、运行:

6、gmtime

#include/***@brief返回tm结构的GMT时间(UTC时间)**Detailedfunctiondescription**@param[in]timep:当前UTC秒数**@return返回当地时间*/structtm*gmtime(consttime_t*timep);

例子:

#include#includetime_tget_utc_time(void){returntime(NULL);}intmain(intargc,char**argv){time_tutc_time=get_utc_time();printf("utc_time=%lds",utc_time);structtm*gmt_tm=gmtime(&utc_time);printf("gmttime=%.4d-%.2d-%.2d%.2d:%.2d:%.2d",gmt_tm->tm_year+1900,gmt_tm->tm_mon+1,gmt_tm->tm_mday,gmt_tm->tm_hour,gmt_tm->tm_min,gmt_tm->tm_sec);return0;}

编译、运行:

localtime和gmtime的区别?

localtime和gmtime都是C语言中的函数,用于将time_t类型的时间转换为struct tm类型的时间。它们的区别在于,gmtime将time_t转换为UTC时间,即世界标准时间,而localtime将time_t转换为本地时间。

例子:使用gmtime与localtime接口返回的小时数来计算当地时区

#include#includetime_tget_utc_time(void){returntime(NULL);}intmain(intargc,char**argv){time_tutc_time=get_utc_time();printf("utc_time=%lds",utc_time);structtm*gmt_tm=gmtime(&utc_time);printf("gmttime=%.4d-%.2d-%.2d%.2d:%.2d:%.2d",gmt_tm->tm_year+1900,gmt_tm->tm_mon+1,gmt_tm->tm_mday,gmt_tm->tm_hour,gmt_tm->tm_min,gmt_tm->tm_sec);intgmt_hour=gmt_tm->tm_hour;structtm*local_tm=localtime(&utc_time);printf("localtime=%.4d-%.2d-%.2d%.2d:%.2d:%.2d",local_tm->tm_year+1900,local_tm->tm_mon+1,local_tm->tm_mday,local_tm->tm_hour,local_tm->tm_min,local_tm->tm_sec);intlocal_hour=local_tm->tm_hour;intlocal_time_zone=local_hour-gmt_hour;if(local_time_zone<-12){local_time_zone+=24;}elseif(local_time_zone>12){local_time_zone-=24;}else{}printf("local_time_zone=%d",local_time_zone);return0;}

编译、运行:

以上就是本次的分享,如果文章有帮助,麻烦帮忙转发,谢谢!

审核编辑:汤梓红

标签:
x 广告
x 广告

Copyright ©  2015-2022 华中公益网版权所有  备案号:京ICP备12018864号-26   联系邮箱:2 913 236 @qq.com