歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux基礎 >> 關於Linux

linux時間函數詳解

我們在編程中可能會經常用到時間,比如取得系統的時間(獲取系統的年、月、日、時、分、秒,星期等 ),或者是隔一段時間去做某事,那麼我們就用到一些時間函數。

linux下存儲時間常見的有兩種存儲 方式,一個是從1970年到現在經過了多少秒,一個是用一個結構來分別存儲年月日時分秒的。

time_t 這種類型就是用來存儲從1970年到現在經過了多少秒,要想更精確一點,可以用結構struct timeval,它精確 到微妙。

struct timeval
{
     long tv_sec ; /*秒*/
     long tv_usec ; /*微秒*/
} ;

而直接存儲年月日的是一個結構:

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*/
     int tm_year ;  /*年, 從1900至今已經多少年*/
     int tm_wday ; /*星期,一周中的第幾天, 從星期日算起,0-6*/
     int tm_yday ; /*從今年1月1日到目前的天數,范圍0-365*/
     int tm_isdst ; /*日光節約時間的旗標*/
} ;

需要特別注意的是,年份是從1900年起至今多少年,而不是直接存儲如2008年,月份從0開始的 ,0表示一月,星期也是從0開始的, 0表示星期日,1表示星期一。

下面介紹一下我們常用的時間函數 :

#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 類似,但是它是經過時 區轉換的時間。
time_t mktime ( struct tm * timeptr ) ;
將 struct tm 結構的時間轉換為從 1970 年至今的秒數
time_t time ( time_t * t ) ;
取得從 1970 年 1 月 1 日至今的秒數。

上面是簡單的介紹,下面通過實戰來看看這些函數的用法 :

/*gettime1.c*/
#include < time.h >
     
int   main ()
{
    time_t   timep ;
       
    time ( & timep ) ; /*獲取time_t類型的當 前時間*/
    /*用gmtime將time_t類型的時間轉換為struct tm類型的時間按,
      然後再用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 ;
}

編譯並運行:

$gcc -o gettime2 gettime2.c

$./gettime2

Sat Jan 12 01:25:29 2008

我看了一本書上面說的這兩個例子如果先後執行的話,兩個的結果除了秒上有差別之外(執行程 序需要時間),應該是一樣的,可是我這裡執行卻發現差了很長時間按,一個是周五,一個是周六,後來我用 date 命令執行了一遍

$date

六  1月 12 01:25:19 CST 2008

我發現date和gettime2比 較一致, 我估計可能gettime1並沒有經過時區的轉換,它們是有差別的。

/*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, asctime 所表示的時間都是UTC時間,只是 數據類型不一樣,而

localtime, ctime 所表示的時間都是經過時區轉換後的時間,它和你用系統命令date 所表示的CST時間應該保持一致。

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

Copyright © Linux教程網 All Rights Reserved