
大家好,我是LinuxZn。
實際開發中,經常要獲取各種時間。下面匯總幾個常用的時間接口:
#include?
/**
?*?@brief?根據系統時鐘的類型,獲取當前時間
?*
?*?Detailed?function?description
?*
?*?@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
?*/
int?clock_gettime?(clockid_t?__clock_id,?struct?timespec?*__tp);
timespec結構體:
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;
????///
????memset(&tp,?0,?sizeof(struct?timespec));
????clock_gettime(CLOCK_REALTIME,?&tp);
????printf("clock_id?=?CLOCK_REALTIME,?sec?=?%ld,?nsec?=?%ld\n",?tp.tv_sec,?tp.tv_nsec);
????///
????memset(&tp,?0,?sizeof(struct?timespec));
????clock_gettime(CLOCK_MONOTONIC,?&tp);
????printf("clock_id?=?CLOCK_MONOTONIC,?sec?=?%ld,?nsec?=?%ld,?sys_time?=?%lld?ns\n",?tp.tv_sec,?tp.tv_nsec,?get_clock_sys_time_ns());
????///
????memset(&tp,?0,?sizeof(struct?timespec));
????clock_gettime(CLOCK_PROCESS_CPUTIME_ID,?&tp);
????printf("clock_id?=?CLOCK_PROCESS_CPUTIME_ID,?sec?=?%ld,?nsec?=?%ld\n",?tp.tv_sec,?tp.tv_nsec);
????///
????memset(&tp,?0,?sizeof(struct?timespec));
????clock_gettime(CLOCK_THREAD_CPUTIME_ID,?&tp);
????printf("clock_id?=?CLOCK_THREAD_CPUTIME_ID,?sec?=?%ld,?nsec?=?%ld\n",?tp.tv_sec,?tp.tv_nsec);
????return?0;
}
編譯、運行:

#include?
/**
?*?@brief?獲取當前時間(從1970年1月1日到目前的時間)
?*
?*?Detailed?function?description
?*
?*?@param[out]?tv:?當前UTC時間
?*?@param[out]?tz:?當前時區信息
?*
?*?@return?成功則返回0,失敗則返回-1
?*/
int?gettimeofday(struct?timeval?*tv,?struct?timezone?*tz);
timeval結構體:
struct?timeval
{
??__time_t?tv_sec;??/*?Seconds.??秒*/
??__suseconds_t?tv_usec;?/*?Microseconds.??微秒*/
};
timezone結構體:
struct?timezone
??{
????int?tz_minuteswest;??/*?Minutes?west?of?GMT.?和Greenwich時間差了多少分鐘?*/
????int?tz_dsttime;??/*?Nonzero?if?DST?is?ever?in?effect.?日光節約時間的狀態??*/
??};
例子:
#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)
{
????///
????printf("sys_time?=?%lld?ms\n",?get_sys_time_ms());
????return?0;
}
編譯、運行:

#include?
/**
?*?@brief?獲取1970-01-01?00:00:00?+0000至今的秒數(UTC)
?*
?*?Detailed?function?description
?*
?*?@param[out]?tloc:?返回的秒存儲指針
?*
?*?@return?成功則返回秒數,失敗則返回-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\n",?utc_time);
????return?0;
}
編譯、運行:

#include?
/**
?*?@brief?將time_t類型的時間轉換為struct?tm類型的時間
?*
?*?Detailed?function?description
?*
?*?@param[in]?timep:?當前UTC秒數
?*
?*?@return?返回當地時間
?*/
struct?tm?*localtime(const?time_t?*timep);
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]?注意: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日開始的天數,其中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\n",?utc_time);
????struct?tm?*local_tm?=?localtime(&utc_time);?
????printf("local?time?=?%.4d-%.2d-%.2d?%.2d:%.2d:%.2d\n",?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;
}
編譯、運行:

#include?
/**
?*?@brief?將time_t類型的時間轉換為struct?tm類型的時間
?*
?*?Detailed?function?description
?*
?*?@param[in]?timep:?當前UTC秒數
?*?@param[out]?timep:?當地時間
?*
?*?@return?返回當地時間
?*/
struct?tm?*localtime_r(const?time_t?*timep,?struct?tm?*result);
localtime不是一個線程安全的函數,關于線程安全的知識點,看閱讀往期文章:如何理解線程安全?。
對于實時性要求較高的系統,多個線程同時調用localtime,可能會造成數據被覆蓋。我們項目中之前是用localtime來獲取系統時間、日期。并使用這個數據去做邏輯,數據異常導致了邏輯異常。
后面使用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\n",?utc_time);
????struct?tm?result;
????struct?tm?*local_tm?=?localtime_r(&utc_time,?&result);?
????printf("local?time?=?%.4d-%.2d-%.2d?%.2d:%.2d:%.2d\n",?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\n",?result.tm_year?+?1900,
????????????????????????????????????????????????????????????result.tm_mon?+?1,
????????????????????????????????????????????????????????????result.tm_mday,
????????????????????????????????????????????????????????????result.tm_hour,
????????????????????????????????????????????????????????????result.tm_min,
????????????????????????????????????????????????????????????result.tm_sec);
????return?0;
}
編譯、運行:

#include?
/**
?*?@brief?返回tm結構的GMT時間(UTC時間)
?*
?*?Detailed?function?description
?*
?*?@param[in]?timep:?當前UTC秒數
?*
?*?@return?返回當地時間
?*/
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\n",?utc_time);
????struct?tm?*gmt_tm?=?gmtime(&utc_time);?
????printf("gmt?time?=?%.4d-%.2d-%.2d?%.2d:%.2d:%.2d\n",?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都是C語言中的函數,用于將time_t類型的時間轉換為struct tm類型的時間。它們的區別在于,gmtime將time_t轉換為UTC時間,即世界標準時間,而localtime將time_t轉換為本地時間。
例子:使用gmtime與localtime接口返回的小時數來計算當地時區
#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\n",?utc_time);
????struct?tm?*gmt_tm?=?gmtime(&utc_time);?
????printf("gmt?time?=?%.4d-%.2d-%.2d?%.2d:%.2d:%.2d\n",?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\n",?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\n",?local_time_zone);
????return?0;
}
編譯、運行:

以上就是本次的分享,如果文章有幫助,麻煩幫忙轉發,謝謝!
由于微信公眾號近期改變了推送規則,為了防止找不到,可以星標置頂,這樣每次推送的文章才會出現在您的訂閱列表里。
猜你喜歡:
Hello系列 | Shell編程必備簡明基礎知識
Hello系列 | 多線程編程基礎!
Hello系列 | cmake簡明基礎知識