1. 程式人生 > >linux/unix下常用時間函式

linux/unix下常用時間函式

1.與時間有關的資料型別

常用的主要有time_t, struct timeb, struct timeval, struct timezone, struct timespec, clock_t,struct tm。
(1).time_t : 這個變數是一個long型,一般用來表示從1970-01-01 00:00:00時以來的秒數,精確度:秒;由函式time()獲取。定義在#include <time.h>中。
目前相當一部分作業系統使用32位二進位制數字表示時間。此類系統的Unix時間戳最多可以使用到格林威治時間2038年01月19日03時14分07秒(二進位制:01111111 11111111 11111111 11111111)。其後一秒,二進位制數字會變為10000000 00000000 00000000 00000000,發生溢位錯誤,造成系統將時間誤解為1901年12月13日20時45分52秒。這很可能會引起軟體故障,甚至是系統癱瘓。使用64位二進位制數字表示時間的系統(最多可以使用到格林威治時間292,277,026,596年12月04日15時30分08秒)則基本不會遇到這類溢位問題。

(2).struct timeb 結構:它有兩個主要成員,一個是秒,另一個是毫秒;精確度:毫秒(10E-3秒)。
由函式ftime()獲取struct timeb結構的時間;其定義如下:

     struct timeb{
        time_t  time; //秒                    
        unsigned short millitm;//毫秒    
        short   timezone; //Minutes west of GMT
        short   dstflag; // Nonzero if Daylight Savings Time used       
}; #include <sys/timeb.h> int ftime(struct timeb* tp);
  呼叫成功返回0;呼叫失敗返回-1。

(3).struct timeval 結構,它有兩個成員;一個是秒,另一個表示微秒,精確度:微秒(10E-6)。
由函式gettime0fday()獲取;
struct timeval結構定義為:

    struct  timeval{
          long  tv_sec;   //秒
          long  tv_usec;  //微秒
      };
  讀取struct timeval結構資料的函式說明:
      #include  <sys/time.h>
      int  gettimeofday(struct  timeval*  tv,struct  timezone*  tz);
  該函式會提取系統當前時間,並把時間分為秒和微秒兩部分填充到結構struct  timeval中;
  同時把當地的時區資訊填充到結構struct  timezone中;
  返回值:成功則返回0,失敗返回-1,錯誤程式碼存於errno。附加說明EFAULT指標tv和tz所指的記憶體空間超出存取許可權。

(4).struct timezone結構的定義為:

    struct  timezone{
         int  tz_minuteswest; 
         int  tz_dsttime;         
      };
  上述兩個結構都定義在/usr/include/sys/time.h。tz_dsttime 所代表的狀態如下:
  DST_NONE
  DST_USA
  DST_AUST
  DST_WET
  DST_MET  
  DST_EET
  DST_CAN
  DST_GB
  DST_RUM
  DST_TUR
  DST_AUSTALT

(5).struct timespec 結構:它是POSIX.4標準定義的一個時間結構,精確度:納秒(10E-9秒)。
由函式 clock_gettime 獲取當前系統struct timespec結構的時間;其定義如下:

     struct  timespec{
          time_t    tv_sec;  //秒         
          long       tv_nsec; //納秒    
     };
     typedef   struct  timespec   timespec_t;
 該結構定義在頭標頭檔案 `/usr/include/time.h` 中;
    int clock_gettime (clock_t which_clock, struct timespec *tp);

(6).clock_t 型別:由函式clock()獲取。

    #include  <time.h>
     clock_t   clock(void);
 linux下該函式以微秒的方式返回CPU的時間;
     typedef    long   clock_t;

(7).struct tm 結構:由函式gmtime()解析time_t得到。

     struct tm*gmtime(const time_t*timep);
  函式說明:gmtime()將引數timep 所指的time_t 結構中的資訊轉換成真實世界所使用的時間日期表示方法,然後
  將結果由結構tm返回。
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;     // 代表目前月份,從1月算起,範圍為 0-11 
    int tm_year;        // 從1900年算起至今的年數 
    int tm_wday;        // 一個星期的日數,從星期一算起,範圍為0-6 
    int tm_yday;        // 從今年1月1日算起至今的天數,範圍為0-365
    int tm_isdst;       //日光節能時間的旗標
};

注意:#include <time.h>和#include <sys/time.h>後者總包括了前者

2.常用的時間函式

Linux下常用時間函式有:clock()、time( )、ctime( )、gmtime( )、localtime( )、mktime( )、asctime( )、difftime( )、gettimeofday( )、settimeofday( )

(1).clock_t clock (void);
標頭檔案:#include <time.h>
函式說明:返回從“開啟這個程式程序”到“程式中呼叫clock()函式”時之間的CPU時鐘計時單元(clock tick)數
返 回 值:標準POSIX平臺下1000000個計時單位為1秒,所以返回的單位相當於us(微秒)
windows下1000個計時單元為1秒,返回的單位相當於ms(毫秒)

(2).time_t time(time_t * t);
標頭檔案:#include <time.h>
函式說明:返回從公元1970年1月1日的UTC時間從0時0分0秒算起到現在所經過的秒數。
如果t 並非空指標的話,此函式也會將返回值存到t指標所指的記憶體。time_t = time(0);或者time_t t;time(&t);
返 回 值:成功則返回秒數,失敗則返回((time_t)-1)值錯誤原因存於errno中。

(3).double difftime(time_t time1, time_t time0);
標頭檔案:#include <time.h>
函式說明:difftime( )比較引數timep1和timep2時間是否相同,並返回之間相差秒數。
返 回 值:返回相差秒數,注意返回型別為double,可正可負。
示例:

#include <stdio.h>
#include <time.h>
int main ()
{
  time_t timer;
  struct tm y2k;
  double seconds;
  y2k.tm_hour = 0;   y2k.tm_min = 0; y2k.tm_sec = 0;
  y2k.tm_year = 100; y2k.tm_mon = 0; y2k.tm_mday = 1;
  time(&timer);  /* get current time; same as: timer = time(NULL)  */
  seconds = difftime(timer,mktime(&y2k));
  printf ("%.f seconds since January 1, 2000 in the current timezone", seconds);
  return 0;
}

(4).time_t mktime(struct tm * timeptr);
標頭檔案:#include <time.h>
函式說明:mktime()用來將引數timeptr所指的tm結構資料轉換成從公元1970年1月1日0時0分0 秒算起至今的UTC時間所經過的秒數。
返 回 值:返回經過的秒數。
示例: 用time()取得時間(秒數),利用localtime()轉換成struct tm,再利用mktine()將struct tm轉換成原來的秒數

#include <stdio.h> 
#include <time.h>
int main(){
time_t timep = time(0);
strcut tm *p;
printf("time() : %d \n",timep);
p=localtime(timep);
timep = mktime(p);
printf("time()->localtime()->mktime():%d\n",timep);
return 0;
}

執行結果:

time():974943297
time()->localtime()->mktime():974943297

(5).char * asctime(const struct tm * timeptr);
標頭檔案:#include <time.h>
函式說明:將引數timeptr所指的tm結構中的資訊轉換成真實世界所使用的時間日期表示方法,然後將結果以字串形態返回。此函式已經由時區轉換成當地時間,字串格式為:”Wed Jun 30 21:49:08 1993\n”
返 回 值:若再呼叫相關的時間日期函式,此字串可能會被破壞。此函式與ctime不同處在於傳入的引數是不同的結構。
附加說明:返回一字串表示目前當地的時間日期
示例:

#include <stdio.h> 
#include <time.h>
int main(){
    time _t timep=time(0);
    printf("%s",asctime(gmtime(&timep)));
    return 0;
}

執行結果:

Sat Oct 28 02:10:06 2015

(6).char * ctime(const time_t *timep);
標頭檔案:#include <time.h>
函式說明: 將時間和日期以字串格式表示
ctime ()將引數timep所指的time_t結構中的資訊轉換成真實世界所使用的時間日期表示方法,然後將結果以字串形態返回。此函式已經由時區轉換成當地 時間,字串格式為”Wed Jun 30 21 :49 :08 1993\n”。若再呼叫相關的時間日期函式,此字串可能會被破壞。
返 回 值:返回一字串表示目前當地的時間日期。
示例:

#include <stdio.h> 
#include <time.h>
int main(){
time_t timep;
time(&timep);
printf("%s",ctime(&timep));
return 0;
}

執行結果:

Sat Oct 28 10:12:05 2015

(7).struct tm* gmtime (const time_t* timep);
標頭檔案:#include <time.h>
函式說明:gmtime()將引數timep 所指的time_t 結構中的資訊轉換成真實世界所使用的時間日期表示方法,
然後將結果由結構tm返回。
返 回 值:返回結構體tm,返回的日期未經時區轉換,而是UTC時間。
示例:

#include <stdio.h> 
#include <time.h>
int main(){
char *wday[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
time_t timep;
struct tm *p;
time(timep);
p=gmtime(timep);
printf("%d/%d/%d",(1900+p->m_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;
}

執行結果:

2015/10/28 Sat 8:15:38

(8).struct tm* localtime (const time_t* _v);
標頭檔案:#include <time.h>
函式說明:將引數timep所指的time_t結構中的資訊轉換成真實世界所使用的時間日期表示方法,然後將結果由結構tm返回。
和gmtime區別就是此函式返回的時間日期已經轉換成當地時區。
返 回 值:返回結構tm代表目前的當地時間,已轉換為當地時區。

(9).int gettimeofday(struct timeval*tv, struct timezone *tz);
標頭檔案:#include <sys/time.h>
函式說明:gettimeofday()會把目前的時間有tv所指的結構返回,timezone 引數若不使用則傳入NULL即可。
當地時區的資訊則放到timeval結構體中。

timeval結構體定義為:

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

timezone結構體定義為:

struct timezone{
int tz_minuteswest;/*和Greenwich時間差了多少分鐘*/
int tz_dsttime;       /*日光節能時間的狀態*/
}

上述兩個結構都定義在/usr/include/sys/time.h。tz_dsttime 所代表的狀態如下:

DST_NONE /*不使用*/
DST_USA /*美國*/
DST_AUST /*澳洲*/
DST_WET /*西歐*/
DST_MET /*中歐*/
DST_EET /*東歐*/
DST_CAN /*加拿大*/
DST_GB /*大不列顛*/
DST_RUM /*羅馬尼亞*/
DST_TUR /*土耳其*/
DST_AUSTALT /*澳洲(1986年以後)*/

返 回 值:成功則返回0,失敗返回-1,錯誤程式碼存於errno。附加說明EFAULT指標tv和tz所指的記憶體空間超出存取許可權。
它獲得的時間精確到微秒(1e-6 s)量級。
示例:

#include <stdio.h> 
#include <sys/time.h>
int main(){
struct timeval tv;
struct timezone tz;
gettimeofday (tv ,  tz);
printf("tv_sec: %d\n", tv.tv_sec) ;
printf("tv_usec: %d\n",tv.tv_usec);
printf("tz_minuteswest: %d\n", tz.tz_minuteswest);
printf("tz_dsttime: %d\n",tz.tz_dsttime);
return 0;
}

執行結果:

tv_sec: 974857339
tv_usec:136996
tz_minuteswest:-540
tz_dsttime:0

(10). int settimeofday ( const struct timeval *tv,const struct timezone *tz);
標頭檔案:#include <sys/time.h>
函式說明:settimeofday()會把目前時間設成由tv所指的結構資訊,當地時區資訊則設成tz所指的結構。詳細的說明請參考gettimeofday()。注意,只有root許可權才能使用此函式修改時間。
返回值:成功則返回0,失敗返回-1,錯誤程式碼存於errno。
錯誤程式碼:
EPERM 並非由root許可權呼叫settimeofday(),許可權不夠。
EINVAL 時區或某個資料是不正確的,無法正確設定時間。

(11).時間格式化函式 strftime
函式:size_t strftime(char *str,size_t max,char *farmat,struct tm *timeptr);
標頭檔案:#include <time.h>
strftime有點像sprintf,其格式由fmt來指定。
輸入:struct tm *timeptr,const char *format
輸出:const char *buf

    %a : 本第幾天名稱,縮寫
     %A : 本第幾天名稱,全稱
     %b : 月份名稱,縮寫
     %B : 月份名稱,全稱
     %c : 與ctime/asctime格式相同
     %d : 本月第幾日名稱,由零算起
     %H : 當天第幾個小時,24小時制,由零算起
     %I : 當天第幾個小時,12小時制,由零算起
     %j : 當年第幾天,由零算起
     %m : 當年第幾月,由零算起
     %M : 該小時的第幾分,由零算起
     %p : AM或PM
     %S : 該分鐘的第幾秒,由零算起
     %U : 當年第幾,由第一個日開始計算
     %W : 當年第幾,由第一個一開始計算
     %w : 當第幾日,由零算起
     %x : 當地日期
     %X : 當地時間
     %y : 兩位數的年份
     %Y : 四位數的年份
     %Z : 時區名稱的縮寫
     %% : %符號
 示例:
int main(void)  
{  
    char strtime[20] = {0};  
    time_t timep;  
    struct tm *p_tm;  
    timep = time(NULL);  
    p_tm = localtime(&timep);  
    strftime(strtime, sizeof(strtime), "%Y-%m-%d %H:%M:%S", p_tm);  
    return 0;  
}  

(12).時間格式化函式 strptime
函式:char * strptime(char *buf,char *format,struct tm *timeptr);
如同scanf一樣,解譯字串成為tm格式
format字串的構建方式和strftime的format字串完全一樣,strptime返回一個指標,
指向轉換過程處理的最後一個字元後面的那個字元,
輸入:const char *buf,const char *format
輸出:struct tm *timeptr

     %h : 與%b%B%c : 讀取%x%X格式
     %C : 讀取%C格式
     %e : 與%d%D : 讀取%m/%d/%y格式
     %k : 與%H%l : 與%I%r : 讀取"%I:%M:%S %p"格式
     %R : 讀取"%H:%M"格式
     %T : 讀取"%H:%M:%S"格式
     %y : 讀取兩位數年份
     %Y : 讀取四位數年份
 示例:
#include <time.h>  
#include <stdio.h>  
#include <string.h>  
int main() {  
    struct tm tm;   
    char buf[255];    
    strptime("24/Aug/2011:09:42:35", "%d/%b/%Y:%H:%M:%S" , &tm);  
    printf("asctime:%s",asctime(&tm)); 
    memset(buf,0,sizeof(buf));  
    strftime(buf, sizeof(buf), "%d %b %Y %H:%M", &tm);  
    printf("%s\n",buf);  
    return 0;  
   }   

(13).獲得ns級時間clock_gettime
函式: int clock_gettime (clock_t which_clock, struct timespec *tp);
標頭檔案:#include<time.h>
which_clock引數解釋
CLOCK_REALTIME:系統實時時間,隨系統實時時間改變而改變,即從UTC1970-1-1 0:0:0開始計時
CLOCK_MONOTONIC:從系統啟動這一刻起開始計時,不受系統時間被使用者改變的影響
CLOCK_PROCESS_CPUTIME_ID:本程序到當前程式碼系統CPU花費的時間
CLOCK_THREAD_CPUTIME_ID:本執行緒到當前程式碼系統CPU花費的時間
struct timespec結構:

     struct timespec{
         time_t tv_sec;    //秒
         long int tv_nsec;//納秒
     };
示例:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main(void)
{
    struct timespec time_start={0, 0},time_end={0, 0};
    clock_gettime(CLOCK_REALTIME, &time_start);
    printf("start time %llus,%llu ns\n", time_start.tv_sec, time_start.tv_nsec);
    clock_gettime(CLOCK_REALTIME, &time_end);
    printf("endtime %llus,%llu ns\n", time_end.tv_sec, time_end.tv_nsec);
    printf("duration:%llus %lluns\n", time_end.tv_sec-time_start.tv_sec, time_end.tv_nsec-time_start.tv_nsec);
    return 0;
}

執行結果:

start time 1397395863s,973618673 ns
endtime 1397395863s,973633297 ns
duration:0s 14624ns