time函數及其用法
一:集中相關類型的定義
1、time_t
time_t實際上是長整數類型,定義為:typedef long time_t; /* time value */2.struct timespec 定義:
typedef long time_t; #ifndef _TIMESPEC #define _TIMESPEC struct timespec { time_t tv_sec; // seconds long tv_nsec; // and nanoseconds }; #endif
struct timespec有兩個成員,一個是秒,一個是納秒, 所以最高精確度是納秒。
一般由函數int clock_gettime(clockid_t, struct timespec *)獲取特定時鐘的時間,常用如下4種時鐘:
CLOCK_REALTIME 統當前時間,從1970年1.1日算起
CLOCK_MONOTONIC 系統的啟動時間,不能被設置
CLOCK_PROCESS_CPUTIME_ID 本進程運行時間
CLOCK_THREAD_CPUTIME_ID 本線程運行時間
struct tm *localtime(const time_t *clock); //線程不安全
struct tm* localtime_r( const time_t* timer, struct tm* result );//線程安全
size_t strftime (char* ptr, size_t maxsize, const char* format,const struct tm* timeptr );
3.timeval
timeval是一個結構體,在time.h中定義為: struct timeval { __time_t tv_sec; /* Seconds. */ __suseconds_t tv_usec; /* Microseconds. */ }; 其中,tv_sec為Epoch(1970-1-1零點零分)到創建struct timeval時的秒數,tv_usec為微秒數,即秒後面的零頭。
4.tm
tm是一個結構體,定義為:struct tm { int tm_sec; /*代表目前秒數,正常範圍為0-59,但允許至61秒*/ int tm_min; /*代表目前分數,範圍0-59*/ int tm_hour; /* 從午夜算起的時數,範圍為0-23 */ int tm_mday; /* 目前月份的日數,範圍01-31 */ int tm_mon; /*代表目前月份,從一月算起,範圍從0-11 */ int tm_year; /*從1900 年算起至今的年數*/ int tm_wday; /* 一星期的日數,從星期一算起,範圍為0-6。*/ int tm_yday; /* Days in year.[0-365] */ int tm_isdst; /*日光節約時間的旗標DST. [-1/0/1]*/ };
二:函數的具體操作
time()函數
原 型:time_t time(time_t * timer) 功 能: 獲取當前的系統時間,返回的結果是一個time_t類型,其實就是一個大整數,其值表示從CUT(Coordinated Universal Time)時間1970年1月1日00:00:00(稱為UNIX系統的Epoch時間)到當前時刻的秒數。然後調用localtime將time_t所表示的CUT時間轉換為本地時間(我們是+8區,比CUT多8個小時)並轉成struct tm類型,該類型的各數據成員分別表示年月日時分秒。 程序例1: time函數獲得日歷時間。日歷時間,是用“從一個標準時間點到此時的時間經過的秒數”來表示的時間。這個標準時間點對不同的編譯器來說會有所不同,但對一個編譯系統來說,這個標準時間點是不變的,該編譯系統中的時間對應的日歷時間都通過該標準時間點來衡量,所以可以說日歷時間是“相對時間”,但是無論你在哪一個時區,在同一時刻對同一個標準時間點來說,日歷時間都是一樣的。#include <time.h> #include <stdio.h> #include <dos.h> int main(void) { time_t t; t = time(NULL); printf("The number of seconds since January 1, 1970 is %ld",t); return 0; } 程序例2: //time函數也常用於隨機數的生成,用日歷時間作為種子。 #include <stdio.h> #include <time.h> #include<stdlib.h> int main(void) { int i; srand((unsigned) time(NULL)); printf("ten random numbers from 0 to 99\n\n"); for(i=0;i<10;i++) printf("%d\n",rand()%100); return 0; } 程序例3: 用time()函數結合其他函數(如:localtime、gmtime、asctime、ctime)可以獲得當前系統時間或是標準時間。 #include <stdio.h> #include <stddef.h> #include <time.h> int main(void) { time_t timer;//time_t就是long int 類型 struct tm *tblock; timer = time(NULL);//這一句也可以改成time(&timer); tblock = localtime(&timer); printf("Local time is: %s\n",asctime(tblock)); return 0; }
gmtime()函數原 型:struct tm *gmtime(long *clock); 功 能:把日期和時間轉換為格林威治(GMT)時間的函數。將參數timep 所指的time_t 結構中的信息轉換成真實世界所使用的時間日期表示方法,然後將結果由結構tm返回。 |
#include "stdio.h" #include "time.h" #include "stdlib.h" int main(void) { time_t t; struct tm *gmt, *area; tzset(); /* tzset()設置時區*/ t = time(NULL); area = localtime(&t); printf("Local time is: %s", asctime(area)); gmt = gmtime(&t); printf("GMT is: %s", asctime(gmt)); return 0; }
localtime()函數
功 能: 把從1970-1-1零點零分到當前時間系統所偏移的秒數時間轉換為日歷時間 。 說 明:此函數獲得的tm結構體的時間,是已經進行過時區轉化為本地時間。 用 法: struct tm *localtime(const time_t *clock); 返回值:返回指向tm 結構體的指針.tm結構體是time.h中定義的用於分別存儲時間的各個量(年月日等)的結構體.
程序例1: #include <stdio.h> #include <stddef.h> #include <time.h> int main(void) { time_t timer;//time_t就是long int 類型 struct tm *tblock; timer = time(NULL); tblock = localtime(&timer); printf("Local time is: %s\n",asctime(tblock)); return 0; } 執行結果: Local time is: Mon Feb 16 11:29:26 2009 程序例2: 上面的例子用了asctime函數,下面這個例子不使用這個函數一樣能獲取系統當前時間。 需要註意的是年份加上1900,月份加上1。 #include<time.h> #include<stdio.h> int main() { struct tm *t; time_t tt; time(&tt); t=localtime(&tt); printf("%4d年%02d月%02d日 %02d:%02d:%02d\n", t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec); return 0; }
localtime()和gmtime()的區別:
gmtime()函數功能類似獲取當前系統時間,只是獲取的時間未經過時區轉換。 localtime函數獲得的tm結構體的時間,是已經進行過時區轉化為本地時間。localtime_r()和gmtime_r()函數
struct tm *gmtime_r(const time_t *timep, struct tm *result);struct tm *localtime_r(const time_t *timep, struct tm *result); gmtime_r()函數功能與此相同,但是它可以將數據存儲到用戶提供的結構體中。 localtime_r()函數功能與此相同,但是它可以將數據存儲到用戶提供的結構體中。它不需要設置tzname。 使用gmtime和localtime後要立即處理結果,否則返回的指針指向的內容可能會被覆蓋。
一個好的方法是使用gmtime_r和localtime_r,由於使用了用戶分配的內存,這兩個函數是不會出錯的。
asctime()函數
功 能: 轉換日期和時間為相應的字符串(英文簡寫形式,形如:Mon Feb 16 11:29:26 2009) 用 法: char *asctime(const struct tm *tblock);ctime()函數
功 能: 把日期和時間轉換為字符串。(英文簡寫形式,形如:Mon Feb 16 11:29:26 2009) 用 法: char *ctime(const time_t *time); 說 明:ctime同asctime的區別在於,ctime是通過日歷時間來生成時間字符串,而asctime是通過tm結構來生成時間字符串。
mktime()函數
功 能:將tm時間結構數據轉換成經過的秒數(日歷時間)。 原 型:time_t mktime(strcut tm * timeptr);。 說 明:mktime()用來將參數timeptr所指的tm結構數據轉換成從公元1970年1月1日0時0分0 秒算起至今的UTC時間所經過的秒數。 返回值:返回經過的秒數。
difftime()函數
功 能:計算時間間隔才長度,以秒為單位,且只能精確到秒。 原 型:double difftime(time_t time1, time_t time0); 說 明:雖然該函數返回值是double類型的,但這並不說明該時間間隔具有同double一樣的精度,這是由它的參數決定的。
strftime()函數
功 能:將時間格式化,或者說:格式化一個時間字符串。我們可以使用strftime()函數將時間格式化為我們想要的格式。 原 型:size_t strftime(char *strDest,size_t maxsize,const char *format,const struct tm *timeptr); 參 數:我們可以根據format指向字符串中格式命令把timeptr中保存的時間信息放在strDest指向的字符串中,最多向strDest中存放maxsize個字符。 返回值:該函數返回向strDest指向的字符串中放置的字符數。 類似於sprintf():識別以百分號(%)開始的格式命令集合,格式化輸出結果放在一個字符串中。
格式化命令說明串strDest中各種日期和時間信息的確切表示方法。格式串中的其他字符原樣放進串中。
格式命令列在下面,它們是區分大小寫的。 %a 星期幾的簡寫 %A 星期幾的全稱 %b 月份的簡寫 %B 月份的全稱 %c 標準的日期的時間串 %C 年份的後兩位數字 %d 十進制表示的每月的第幾天 %D 月/天/年 %e 在兩字符域中,十進制表示的每月的第幾天 %F 年-月-日 %g 年份的後兩位數字,使用基於周的年 %G 年份,使用基於周的年 %h 簡寫的月份名 %H 24小時制的小時 %I 12小時制的小時 %j 十進制表示的每年的第幾天 %m 十進制表示的月份 %M 十時制表示的分鐘數 %n 新行符 %p 本地的AM或PM的等價顯示 %r 12小時的時間 %R 顯示小時和分鐘:hh:mm %S 十進制的秒數 %t 水平制表符 %T 顯示時分秒:hh:mm:ss %u 每周的第幾天,星期一為第一天 (值從0到6,星期一為0) %U 第年的第幾周,把星期日作為第一天(值從0到53) %V 每年的第幾周,使用基於周的年 %w 十進制表示的星期幾(值從0到6,星期天為0) %W 每年的第幾周,把星期一做為第一天(值從0到53) %x 標準的日期串 %X 標準的時間串 %y 不帶世紀的十進制年份(值從0到99) %Y 帶世紀部分的十制年份 %z,%Z 時區名稱,如果不能得到時區名稱則返回空字符。 %% 百分號 提示:與 gmstrftime() 的行為相同,不同的是返回時間是本地時間。
三:sleep usleep clock
1..Sleep函數(不同平臺、編譯器之間可能函數名,函數參數單位不一樣)
頭文件:#include<windows.h>
定義函數:unsigned sleep(unsigned seconds);
函數說明:此函數執行掛起一段時間。
example:(對於windows+codeblocks下,Sleep(),單位為ms)
#include<stdio.h> #include<windows.h> main() { int i,j; i=time((time_t*)NULL); Sleep(2000); //延遲2s j=time((time_t*)NULL); printf("延時了%d秒",j-i); }
2.clock函數
函數定義:clock_t clock(void) ;
函數說明:該程序從啟動到函數調用占用CPU的時間。
example:
#include<stdio.h> #include<windows.h> main() { int i,j; Sleep(2000); i=clock(); Sleep(2000); j=clock(); printf("開始%d\n結束%d\n經過%d\n",i,j,j-i); }
3. usleep
頭文件: #include <unistd.h>
功 能: usleep功能把進程掛起一段時間, 單位是微秒(百萬分之一秒);
語 法: void usleep(int micro_seconds);
返回值: 無
內容說明:本函數可暫時使程序停止執行。參數 micro_seconds 為要暫停的微秒數(us)。
註 意:
這個函數不能工作在windows 操作系統中。用在Linux的測試環境下面。
參 見:usleep() 與sleep()類似,用於延遲掛起進程。進程被掛起放到reday queue。
是一般情況下,延遲時間數量級是秒的時候,盡可能使用sleep()函數。
如果延遲時間為幾十毫秒(1ms = 1000us),或者更小,盡可能使用usleep()函數。這樣才能最佳的利用CPU時間
時鐘換算:
微秒,時間單位,符號us(英語:microsecond ).
1微秒等於百萬分之一秒(10的負6 次方秒)
0.000 001 微秒 = 1皮秒
0.001 微秒 = 1納秒
1,000 微秒 = 1毫秒
1,000,000 微秒 = 1秒
1s = 1000ms
1ms = 1000μs
1μs = 1000ns
1ns = 1000ps
time函數及其用法