linux下存儲時間常見的有兩種存儲方式,一個是從1970年01月01日 0:00:00到如今通過了多少秒,一個是用一個結構來分別存儲年月日時分秒的。time_t 這種類型就是用來存儲從1970年到如今通過了多少秒,要想更精確一點,能夠用結構struct timeval,它精確到微妙。linux
struct timeval { long tv_sec; /*秒*/ long tv_usec; /*微秒*/ };
而直接存儲年月日的是一個結構:shell
struct tm { int tm_sec; /*秒,正常範圍0-59, 但容許至61*/ int tm_min; /*分鐘,0-59*/ int tm_hour; /*小時, 0-23*/ int tm_mday; /*日,即一個月中的第幾天,1-31*/ int tm_mon; /*月, 從一月算起,0-11*/ 1+p->tm_mon; int tm_year; /*年, 從1900至今已經多少年*/ 1900+ p->tm_year; int tm_wday; /*星期,一週中的第幾天, 從星期日算起,0-6*/ int tm_yday; /*從今年1月1日到目前的天數,範圍0-365*/ int tm_isdst; /*日光節約時間的旗標*/ };
須要特別注意的是,年份是從1970年01月01日 0:00:00開始計算的。多線程
下面介紹一下咱們經常使用的時間函數:(參考連接:http://www.cplusplus.com/reference/ctime/)函數
#include <time.h> char *asctime(const struct tm* timeptr); 將結構中的信息轉換爲真實世界的時間,以字符串的形式顯示 char *ctime(const time_t *timep); 將timep轉換爲真是世界的時間,以字符串顯示,它和asctime不一樣就在於傳入的參數形式不同 double difftime(time_t time1, time_t time2); 返回兩個時間相差的秒數 int gettimeofday(struct timeval *tv, struct timezone *tz); 返回當前距離1970年的秒數和微妙數,後面的tz是時區 struct tm* gmtime(const time_t *timep); 將time_t表示的時間轉換爲沒有通過時區轉換的UTC時間,是一個struct tm結構指針 stuct tm* localtime(const time_t *timep); 和gmtime相似,可是它是通過時區轉換的時間。 另外須要注意的是不能連續使用localtime,若有需求應該保存上一個timep的值。(多線程下也須要注意) time_t mktime(struct tm* timeptr); 將struct tm 結構的時間轉換爲從1970年至今的秒數 time_t time(time_t *t); 取得從1970年1月1日至今的秒數。
上面是簡單的介紹,下面經過實戰來看看這些函數的用法:
spa
/*gettime1.c*/ #include <time.h> int main() { time_t timep; time(&timep); /*獲取time_t類型的當前時間*/ /*用gmtime將time_t類型的時間轉換爲struct tm類型的時間按,//沒有通過時區轉換的UTC時間 而後再用asctime轉換爲咱們常見的格式 Fri Jan 11 17:25:24 2008 */ printf("%s", asctime(gmtime(&timep))); return 0; }
編譯並運行:線程
$gcc -o gettime1 gettime1.c $./gettime1 Fri Jan 11 17:04:08 2008
下面是直接把time_t類型的轉換爲咱們常見的格式:指針
/* gettime2.c*/ #include <time.h> int main() { time_t timep; time(&timep); /*獲取time_t類型當前時間*/ /*轉換爲常見的字符串:Fri Jan 11 17:04:08 2008*/ printf("%s", ctime(&timep)); return 0; }
編譯並運行:code
$gcc -o gettime2 gettime2.c $./gettime2 Sat Jan 12 01:25:29 2008
兩個的結果除了秒上有差異以外(執行程序須要時間),應該是同樣的,但是我這裏執行卻發現差了很長時間按,一個是週五,一個是週六,後來我用 date 命令執行了一遍(備註:date -u顯示UTC時間)字符串
$date 六 1月 12 01:25:19 CST 2008
我發現date和gettime2比較一致, 我估計可能gettime1並無通過時區的轉換,它們是有差異的。get
/*gettime3.c */ #include <time.h> int main() { char *wday[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; time_t timep; struct tm *p; time(&timep); /*得到time_t結構的時間,UTC時間*/ p = gmtime(&timep); /*轉換爲struct tm結構的UTC時間*/ printf("%d/%d/%d ", 1900 + p->tm_year, 1+ p->tm_mon, p->tm_mday); printf("%s %d:%d:%d\n", wday[p->tm_wday], p->tm_hour, p->tm_min, p->tm_sec); return 0; }
編譯並運行:
$gcc -o gettime3 gettime3.c $./gettime3 2008/1/11 Fri 17:42:54
從這個時間結果上來看,它和gettime1保持一致。
/*gettime4.c*/ #include <time.h> int main() { char *wday[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; time_t timep; struct tm *p; time(&timep); /*得到time_t結構的時間,UTC時間*/ p = localtime(&timep); /*轉換爲struct tm結構的當地時間*/ printf("%d/%d/%d ", 1900 + p->tm_year, 1+ p->tm_mon, p->tm_mday); printf("%s %d:%d:%d\n", wday[p->tm_wday], p->tm_hour, p->tm_min, p->tm_sec); return 0; }
編譯並運行:
$gcc -o gettime4 gettime4.c $./gettime4 2008/1/12 Sat 1:49:29
從上面的結果咱們能夠這樣說:
time, gmtime 所表示的時間都是UTC時間,只是數據類型不同,
而localtime 所表示的時間都是通過時區轉換後的時間,它和你用系統命令date所表示的CST時間應該保持一致。
(備註:CST 中央標準時間 GMT 格林威治時間 UTC 世界協調時間 EST 東部標準時間)
/*gettime5.c*/ #include <time.h> int main() { time_t timep; struct tm *p; time(&timep); /*當前time_t類型UTC時間*/ printf("time():%d\n",timep); p = localtime(&timep); /*轉換爲本地的tm結構的時間按*/ timep = mktime(p); /*從新轉換爲time_t類型的UTC時間,這裏有一個時區的轉換*/ printf("time()->localtime()->mktime(): %d\n", timep); return 0; }
編譯並運行:
$gcc -o gettime5 gettime5.c $./gettime5 time():1200074913 time()->localtime()->mktime(): 1200074913
這裏面把UTC時間按轉換爲本地時間,而後再把本地時間轉換爲UTC時間,它們轉換的結果保持一致。
/*gettime6.c */ #include <time.h> int main() { time_t timep; struct tm *p; time(&timep); /*獲得time_t類型的UTC時間*/ printf("time():%d\n",timep); p = gmtime(&timep); /*獲得tm結構的UTC時間*/ timep = mktime(p); /*轉換,這裏會有時區的轉換*/ printf("time()->gmtime()->mktime(): %d\n", timep); return 0; }
編譯並運行:
$gcc -o gettime6 gettime6.c $./gettime6 time():1200075192 time()->gmtime()->mktime(): 1200046392
從這裏面咱們能夠看出,轉換後時間不一致了,計算一下,整整差了8個小時( (1200075192-1200046392)/3600 = 8),說明mktime會把本地時間轉換爲UTC時間,這裏面原本就是UTC時間,因而再弄個時區轉換,結果差了8個小時,用的時候應該注意。