1.結構體定義
timeval結構體在頭文件為sys/time.h中,定義如下:
struct timeval { time_t tv_sec; /* seconds */ suseconds_t tv_usec; /* microseconds */ };
該結構體以1970-01-01 00:00:00 +0000 (UTC),也就是Unix中的Epoch作為0,之后的時間都是相對於Epoch流逝的秒和毫秒數。其中tv_sec是秒,tv_usec是微秒(microsecond ),即10-6秒,而不是毫秒(millisecond),10-3秒。
2. 關聯函數
gettimeofday
位於頭文件sys/time.h中,函數聲明如下:
int gettimeofday(struct timeval *tv, struct timezone *tz);
用於獲取調用該代碼時,距離Epoch的時間。
第一個參數不用多說,第二個參數也是結構體,定義如下:
struct timezone { int tz_minuteswest; /* minutes west of Greenwich */ int tz_dsttime; /* type of DST correction */ };
根據Linux的手冊中關於函數gettimeofday的描述(man gettimeofday):
The use of the timezone structure is obsolete; the tz argument should normally be specified as NULL
這種使用方式是過時的,該處通常提供NULL作為參數。
測試代碼:
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <sys/time.h> #include <errno.h> #include <unistd.h> int main() { struct timeval tv;int i; for(i=0;i<5;i++) { gettimeofday(&tv, NULL); printf("%ld.%06ld\n", tv.tv_sec, tv.tv_usec); sleep(1); } return 0; }
運行效果如下(和運行時間有關):
1610953256.769513
1610953257.769901
1610953258.770804
1610953259.771444
1610953260.771719
可以看到,並不是非常精確的1秒延時,多次測試發現延時都會滯后一點不過在一般的應用場合是足夠了,例如,我們可以兩次調用這個函數,測試一段代碼執行所消耗的時間等。
另外一個與之相關的函數是settimeofday,看名字就知道是和gettimeofday對應的,這里就不去展開討論了。
3. 同日期之間的轉換
在獲取了相對於Epoch的時間以后,相應的日期也就可以確定了,這個時候就要用到time.h中的結構體struct tm了。結構體定義如下:
struct tm
{ int tm_sec; /* Seconds (0-60) */ int tm_min; /* Minutes (0-59) */ int tm_hour; /* Hours (0-23) */ int tm_mday; /* Day of the month (1-31) */ int tm_mon; /* Month (0-11) */ int tm_year; /* Year - 1900 */ int tm_wday; /* Day of the week (0-6, Sunday = 0) */ int tm_yday; /* Day in the year (0-365, 1 Jan = 0) */ int tm_isdst; /* Daylight saving time */ };
與之相關的幾個函數分別是gmtime\localtime、mktime。
先說說將時間戳轉換為日期的函數gmtime和localtime,前者是GMT時間,而后者是本地時間,例如現在北京時間是下午16點,則GMT時間實際上是當日的上午8點(我們在東八區,記作GMT+8)。
gmtime定義如下:
struct tm *gmtime(const time_t *timep);
接收一個time_t*的指針,然后將其轉換為了代表gmt時間的結構體t指針,需要年月日時分秒等,都可以從這個返回的tm結構體中獲取,測試代碼如下。
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <sys/time.h> #include <errno.h> #include <unistd.h> int main() { struct timeval tv; struct tm* st; gettimeofday(&tv, NULL); printf("%ld.%06ld\n", tv.tv_sec, tv.tv_usec); st=gmtime(&tv.tv_sec); printf("%02d:%02d:%02d\n",st->tm_hour,st->tm_min,st->tm_sec); return 0; }
這將顯示當前的時間,由於使用的是GMT時間,因此,比北京時間慢了8小時,如果使用localtime而不是gmtime的話,則和北京時間相同。
反過來,如果我們向知道某個日期所對應的相對Epoch時間是多少,則可以使用mktime函數,這個函數原型如下:
time_t mktime(struct tm *tm);
就是將tm結構體指針轉換為time_t,測試代碼如下:
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <sys/time.h> #include <errno.h> #include <unistd.h> int main() { time_t tt; struct tm st; st.tm_year=121;//year=1900+121=2021 st.tm_mon=0;//for Jaunary st.tm_mday=18; st.tm_hour=7; st.tm_min=39; st.tm_sec=34; tt=mktime(&st); printf("%ld\n",tt); return 0; }