c time類型詳解

    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個小時,用的時候應該注意。

相關文章
相關標籤/搜索