1. 程式人生 > >time庫的使用和解析(time.h)

time庫的使用和解析(time.h)

工作中用到了time庫。記下一些問題和分析,供自己以後回憶也分享給大家。

這裡用Arduino的time庫做示例。

首先,幾個容易搞混淆的概念。

時間庫內幾乎所有的資料都在以下兩個資料型別之間相互轉換。

1.時間型別time_t

時間型別time_t雖然只是一個32位無符號整數,但該型別的資料均代表從2000年1月1日0點0分起開始計時的秒數。(視情況而定。Unix時間是從1970年1月1日0點0分開始計數的有符號整數。這方面不同的庫其實implement不同的實現,不需要多在意)

2.時間結構體tm

    struct tm {
        int8_t          tm_sec; /**< seconds after the minute - [ 0 to 59 ] */
        int8_t          tm_min; /**< minutes after the hour - [ 0 to 59 ] */
        int8_t          tm_hour; /**< hours since midnight - [ 0 to 23 ] */
        int8_t          tm_mday; /**< day of the month - [ 1 to 31 ] */
        int8_t          tm_wday; /**< days since Sunday - [ 0 to 6 ] */
        int8_t          tm_mon; /**< months since January - [ 0 to 11 ] */
        int16_t         tm_year; /**< years since 1900 */
        int16_t         tm_yday; /**< days since January 1 - [ 0 to 365 ] */
        int16_t         tm_isdst; /**< Daylight Saving Time flag */
    };

可以看到所有項均很好理解,除了tm_year。tm_year代表了從1900年開始計算的年數(即2018年時該項的值為2018-1900 = 118)。

雖然因為時區不同,夏令時不同等原因將導致各地日期時間均不相同,然而UTC(標準時間)所有人都一樣。所以一切系統時間以UTC為準。再通過函式將系統時間轉換為UTC時間結構體或本地時間結構體。

第一次使用time庫需要做一些設定。

設定相關函式:

時區設定:

void            set_zone(int32_t);

時區設定函式使用引數(ONE_HOUR*時區)。ONE_HOUR為一小時的秒數,所以直接用3600也可。

比如中國為+8區,則

set_zone(ONE_HOUR * 8);

時區設定將影響

struct tm      *localtime(const time_t * timer);

所返回的tm結構體和其他將會被轉換為本地時間結構體/解析本地時間結構體返回系統時間的函式。

夏令時設定:

void            set_dst(int (*) (const time_t *, int32_t *));

夏令時可不設定。預設沒有。

系統時間設定:

void            set_system_time(time_t timestamp);

系統時間設定時引數為一個time_t(uint32_t)數。若寫入當前時間的time_t值則系統時間將更新為當前時間。若該值來源不同(UNIX時間或其他不同格式)則加相應的OFFSET。

時間維護:

void            system_tick(void);

這個函式非常重要。我之前因為沒使用這個函式導致系統時間不走。這個函式需放入系統的一個1s的中斷函式中,才能讓系統時間開始工作。在windows或其他系統下,這個函式很可能已經被系統維護了,所以並不需要在意。但是自己開發的嵌入式系統/程式裡則要記得自行維護這個函式。

剩下就是使用了。

time_t          time(time_t *timer);    //獲取當前系統時間


time_t          mktime(struct tm * timeptr);   //將一個tm結構體轉變成time_t。使用此函式時,被        
                                               //轉換的源tm結構體被認為是本地時間。使用時只需填 
                                               //充基本時間(年月日時分秒)。填充其他項將被忽 
                                               //略,且會被改寫為合適的值。

time_t          mk_gmtime(const struct tm * timeptr);    //與上一個類似,不同處在於源tm結構體 
                                                         //被認為時UTC時間。且成功轉換後不會改 
                                                         //寫其他項。

struct tm      *gmtime(const time_t * timer);    //將time_t轉換為tm結構體。表達為UTC時間。

struct tm      *localtime(const time_t * timer);  //同上。表達為本地時間。

char           *asctime(const struct tm * timeptr);  //將tm結構體轉換為ascii字串。