大家好,我是LinuxZn。
實際開發(fā)中,經(jīng)常要獲取各種時間。下面匯總幾個常用的時間接口:
1、clock_gettime
?
#include?/** ?*?@brief?根據(jù)系統(tǒng)時鐘的類型,獲取當(dāng)前時間 ?* ?*?Detailed?function?description ?* ?*?@param[in]?__clock_id:?系統(tǒng)時鐘的類型。常用取值: ??????????????????????????-?CLOCK_REALTIME:?從1970年1月1日到目前的時間 ??????????????????????????-?CLOCK_MONOTONIC:?系統(tǒng)啟動時間 ??????????????????????????-?CLOCK_PROCESS_CPUTIME_ID:?本進程運行時間 ??????????????????????????-?CLOCK_THREAD_CPUTIME_ID:?本線程運行的時間 ?*?@param[out]?__tp:?存放當(dāng)前的時間。 ?* ?*?@return?成功則返回0,失敗則返回-1 ?*/ int?clock_gettime?(clockid_t?__clock_id,?struct?timespec?*__tp);
?
timespec結(jié)構(gòu)體:
?
struct?timespec { ??__time_t?tv_sec;??/*?Seconds.?秒?*/ ??__syscall_slong_t?tv_nsec;?/*?Nanoseconds.??納秒*/ };
?
例子:
?
#include?#include? #include? long?long?get_clock_sys_time_ns(void) { ????struct?timespec?tp; ????long?long?time_ns?=?0; ????clock_gettime(CLOCK_MONOTONIC,?&tp); ????time_ns?=?(long?long)tp.tv_sec?*?1000000000?+?tp.tv_nsec; ????return?time_ns; } int?main(void) { ????struct?timespec?tp; ????/// ?
編譯、運行:
2、gettimeofday
?
#include?/** ?*?@brief?獲取當(dāng)前時間(從1970年1月1日到目前的時間) ?* ?*?Detailed?function?description ?* ?*?@param[out]?tv:?當(dāng)前UTC時間 ?*?@param[out]?tz:?當(dāng)前時區(qū)信息 ?* ?*?@return?成功則返回0,失敗則返回-1 ?*/ int?gettimeofday(struct?timeval?*tv,?struct?timezone?*tz); ?
timeval結(jié)構(gòu)體:
?
struct?timeval { ??__time_t?tv_sec;??/*?Seconds.??秒*/ ??__suseconds_t?tv_usec;?/*?Microseconds.??微秒*/ };?
timezone結(jié)構(gòu)體:
?
struct?timezone ??{ ????int?tz_minuteswest;??/*?Minutes?west?of?GMT.?和Greenwich時間差了多少分鐘?*/ ????int?tz_dsttime;??/*?Nonzero?if?DST?is?ever?in?effect.?日光節(jié)約時間的狀態(tài)??*/ ??};?
例子:
?
#include?#include? #include? long?long?get_sys_time_ms(void) { ????long?long?time_ms?=?0; ????struct?timeval?tv; ????gettimeofday(&tv,?NULL); ????time_ms?=?((long?long)tv.tv_sec*1000000?+?tv.tv_usec)?/?1000; ????return?time_ms; } int?main(void) { ????/// ?
編譯、運行:
3、time
?
#include?/** ?*?@brief?獲取1970-01-01?0000?+0000至今的秒數(shù)(UTC) ?* ?*?Detailed?function?description ?* ?*?@param[out]?tloc:?返回的秒存儲指針 ?* ?*?@return?成功則返回秒數(shù),失敗則返回-1,錯誤原因存在errno中。 ?*/ time_t?time(time_t?*tloc); ?
time_t的類型:
?
typedef?long?time_t;?
例子:
?
#include?#include? time_t?get_utc_time(void) { ????return?time(NULL); } int?main(int?argc,?char?**argv) { ????time_t?utc_time?=?get_utc_time(); ????printf("utc_time?=?%ld?s ",?utc_time); ????return?0; } ?
編譯、運行:
4、localtime
?
#include?/** ?*?@brief?將time_t類型的時間轉(zhuǎn)換為struct?tm類型的時間 ?* ?*?Detailed?function?description ?* ?*?@param[in]?timep:?當(dāng)前UTC秒數(shù) ?* ?*?@return?返回當(dāng)?shù)貢r間 ?*/ struct?tm?*localtime(const?time_t?*timep); ?
tm結(jié)構(gòu)體:
?
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]?注意:0代表1月,以此類推*/ ??int?tm_year;???/*?Year?-?1900.??該值為實際年份減去1900*/ ??int?tm_wday;???/*?Day?of?week.?[0-6]?注意:0代表星期一,以此類推*/ ??int?tm_yday;???/*?Days?in?year.[0-365]?從每年的1月1日開始的天數(shù),其中0代表1月1日,以此類推*/ ??int?tm_isdst;???/*?DST.??[-1/0/1]?夏玲時標識符*/ };?
例子:
?
#include?#include? time_t?get_utc_time(void) { ????return?time(NULL); } int?main(int?argc,?char?**argv) { ????time_t?utc_time?=?get_utc_time(); ????printf("utc_time?=?%ld?s ",?utc_time); ????struct?tm?*local_tm?=?localtime(&utc_time);? ????printf("local?time?=?%.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); ????return?0; } ?
編譯、運行:
5、localtime_r
?
#include?/** ?*?@brief?將time_t類型的時間轉(zhuǎn)換為struct?tm類型的時間 ?* ?*?Detailed?function?description ?* ?*?@param[in]?timep:?當(dāng)前UTC秒數(shù) ?*?@param[out]?timep:?當(dāng)?shù)貢r間 ?* ?*?@return?返回當(dāng)?shù)貢r間 ?*/ struct?tm?*localtime_r(const?time_t?*timep,?struct?tm?*result); ?
localtime不是一個線程安全的函數(shù),關(guān)于線程安全的知識點,看閱讀往期文章:如何理解線程安全?。
對于實時性要求較高的系統(tǒng),多個線程同時調(diào)用localtime,可能會造成數(shù)據(jù)被覆蓋。我們項目中之前是用localtime來獲取系統(tǒng)時間、日期。并使用這個數(shù)據(jù)去做邏輯,數(shù)據(jù)異常導(dǎo)致了邏輯異常。
后面使用localtime_r來替代,問題解決。
例子:
?
#include?#include? time_t?get_utc_time(void) { ????return?time(NULL); } int?main(int?argc,?char?**argv) { ????time_t?utc_time?=?get_utc_time(); ????printf("utc_time?=?%ld?s ",?utc_time); ????struct?tm?result; ????struct?tm?*local_tm?=?localtime_r(&utc_time,?&result);? ????printf("local?time?=?%.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("result?time?=?%.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); ????return?0; } ?
編譯、運行:
6、gmtime
?
#include?/** ?*?@brief?返回tm結(jié)構(gòu)的GMT時間(UTC時間) ?* ?*?Detailed?function?description ?* ?*?@param[in]?timep:?當(dāng)前UTC秒數(shù) ?* ?*?@return?返回當(dāng)?shù)貢r間 ?*/ struct?tm?*gmtime(const?time_t?*timep); ?
例子:
?
#include?#include? time_t?get_utc_time(void) { ????return?time(NULL); } int?main(int?argc,?char?**argv) { ????time_t?utc_time?=?get_utc_time(); ????printf("utc_time?=?%ld?s ",?utc_time); ????struct?tm?*gmt_tm?=?gmtime(&utc_time);? ????printf("gmt?time?=?%.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); ????return?0; } ?
編譯、運行:
localtime和gmtime的區(qū)別?
localtime和gmtime都是C語言中的函數(shù),用于將time_t類型的時間轉(zhuǎn)換為struct tm類型的時間。它們的區(qū)別在于,gmtime將time_t轉(zhuǎn)換為UTC時間,即世界標準時間,而localtime將time_t轉(zhuǎn)換為本地時間。
例子:使用gmtime與localtime接口返回的小時數(shù)來計算當(dāng)?shù)貢r區(qū)
?
#include?#include? time_t?get_utc_time(void) { ????return?time(NULL); } int?main(int?argc,?char?**argv) { ????time_t?utc_time?=?get_utc_time(); ????printf("utc_time?=?%ld?s ",?utc_time); ????struct?tm?*gmt_tm?=?gmtime(&utc_time);? ????printf("gmt?time?=?%.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); ????int?gmt_hour?=?gmt_tm->tm_hour; ????struct?tm?*local_tm?=?localtime(&utc_time);? ????printf("local?time?=?%.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); ????int?local_hour?=?local_tm->tm_hour; ????int?local_time_zone?=?local_hour?-?gmt_hour; ????if?(local_time_zone?-12)? ????{ ????????local_time_zone?+=?24;? ????}? ????else?if?(local_time_zone?>?12)? ????{ ????????local_time_zone?-=?24; ????}else{} ????printf("local_time_zone?=?%d ",?local_time_zone); ????return?0; } ?
編譯、運行:
以上就是本次的分享,如果文章有幫助,麻煩幫忙轉(zhuǎn)發(fā),謝謝!
審核編輯:湯梓紅
評論
查看更多