1. time_t
time_t記錄自1970年1月1日凌晨以來的秒數,在Linux/Unix上定義爲long int類型,在32位系統上,time_t最多隻能記錄2,147,483,647秒,也就是說到了2038年將會產生溢出,但在64位系統上不會出現此問題。
time_t time(time_t *t);例子如下:
- #include <stdio.h>
- #include <time.h>
- int main(void)
- {
- time_t sec;
- sec = time(NULL);
- printf("%ld\n", sec);
- return 0;
- }
double difftime(time_t time1, time_t time0);用於比較兩個time_t類型的值。
2. struct tm
由time_t可以知道,操作系統使用的是long int類型的值來存儲時間,但對於用戶來說肯定是不好理解,所以就有了這裏的struct tm類型,定義如下:
struct tm {
int tm_sec; /* seconds */ int tm_min; /* minutes */ int tm_hour; /* hours */ int tm_mday; /* day of the month */ int tm_mon; /* month */ int tm_year; /* year */ int tm_wday; /* day of the week */ int tm_yday; /* day in the year */ int tm_isdst; /* daylight saving time */ }; ----------------------------------------------------------------- tm_sec | 秒,範圍是0~59。 tm_min | 分,範圍是0~59。 tm_hour | 時,範圍是0~23。 tm_mday | 日,範圍是1~31。 tm_mon | 月,範圍是0~11,注意是0到11。 tm_year | 年,自1900以來的年數。 tm_wday | 星期幾,從星期天開始計算,範圍是0~6。 tm_yday | 一年中的哪一天,0~365。 tm_isdst | 夏令時間(DST)的一個標誌。 -----------------------------------------------------------------
那怎麼能得到這個時間呢,有兩個函數gmtime和localtime,原型如下:
struct tm *gmtime(const time_t *timep); struct tm *localtime(const time_t *timep);例子如下:
- #include <stdio.h>
- #include <time.h>
- int main(void)
- {
- const char *const days[] = {"星期天", "星期一", "星期二",
- "星期三", "星期四", "星期五", "星期六"};
- time_t sec;
- struct tm *n;
- sec = time(NULL);
- n = localtime(&sec);
- printf("%d年 %d月 %d日 %s %d:%d:%d\n",
- n->tm_year + 1900,
- n->tm_mon + 1,
- n->tm_mday,
- days[n->tm_wday],
- n->tm_hour,
- n->tm_min,
- n->tm_sec);
- return 0;
- }
再介紹兩個函數,ctime和asctime,原型如下:
char *ctime(const time_t *timep); char *asctime(const struct tm *tm);例子如下:
- #include <stdio.h>
- #include <time.h>
- int main(void)
- {
- time_t sec;
- sec = time(NULL);
- printf("%s\n", ctime(&sec));
- return 0;
- }
Mon Nov 11 17:40:34 2013
也就說ctime函數將time_t類型的值轉換爲一個時間相關的字符串,而asctime同ctime函數不同的是,asctime的參數爲strut tm類型指針,而ctime的參數爲time_t類型的指針,只是參數類型不一樣,但是結果都是一樣的,都是獲取一個時間相關的字符串。
那既然有time函數將time_t值轉換爲struct tm類型值,那自然也有將struct tm類型值轉換爲time_t類型的值,函數爲mktime,原型爲:
time_t mktime(struct tm *tm);
3. 關於獲取和設置系統時鐘
前面使用的是time來獲取一個時間值,但是它的精度只能達到秒級,如果只是做一個日曆足夠了,但是如果想獲取更精確的時間呢,比如想計算程序的執行時間,顯然time函數不能滿足我們的要求,那就只能使用這裏的gettimeofday函數了,原型如下:
int gettimeofday(struct timeval *tv, struct timezone *tz);
其中struct timeval結構類型定義如下:
struct timeval {
time_t tv_sec; /* seconds */ suseconds_t tv_usec; /* microseconds */ };struct timeval結構類型提供了一個微秒級成員tv_usec,它的類型同樣是一個整型類型。
而gettimeofday函數的tz參數用於獲取時區信息,在Linux中通常設置爲NULL,程序例子如下:
- #include <stdio.h>
- #include <sys/time.h>
- int main(void)
- {
- struct timeval tv;
- int ret;
- ret = gettimeofday(&tv, NULL);
- if (ret) {
- perror("gettimeofday");
- } else {
- printf("seconds=%ld useconds=%ld\n",
- (long)tv.tv_sec, (long)tv.tv_usec);
- }
- return 0;
- }
那如何去設置設置系統時鐘呢?這裏要介紹兩個函數,同time和gettimeofday對應,stime和settimeofday,原型如下:
int stime(time_t *t); int settimeofday(const struct timeval *tv, const struct timezone *tz);只是settimeofday設置的時間比stime更精確罷了。
4. 關於睡眠延時
睡眠延時先介紹兩個函數sleep和usleep,原型如下:
unsigned int sleep(unsigned int seconds); int usleep(useconds_t usec);sleep用於睡眠多少秒,而usleep爲睡眠多少微妙。
使用這兩個函數需要包含頭文件unistd.h。
5. 定時器
alarm函數原型如下:
unsigned alarm(unsigned seconds);
例子如下:
- #include <stdio.h>
- #include <unistd.h>
- #include <signal.h>
- void alarm_handler(int signum)
- {
- printf("Five seconds passed!\n");
- }
- void func(void)
- {
- signal(SIGALRM, alarm_handler);
- alarm(5);
- pause();
- }
- int main(void)
- {
- func();
- return 0;
- }
除了alarm外,還可以使用setitimer來設置定時器,使用getitimer來獲取定時器的狀態,原型如下:
int setitimer(int which, const struct itimerval *restrict value, struct itimerval *restrict ovalue); int getitimer(int which, struct itimerval *value);需要包含頭文件sys/time.h
which參數有三種取值:
ITIMER_REAL 按實際時間記時,時間到了之後發送SIGALRM信號,相當於alarm。 ITIMER_VIRTUAL 僅當進程執行時才進行記時,發送SIGVTALRM信號。 ITIMER_PROF 當進程執行時和系統執行該進程時都記時,發送的是SIGPROF信號。
struct itimerval用來指定定時時間,定義如下:
struct itimerval { struct timerval it_interval; /* next value */ struct timerval it_value; /* current value */ };struct timeval結構前面都見過了,這裏就不再描述了。
在setitimer函數中,ovalue如果不爲空,則保留上次調用設置的值。例子如下:
- #include <stdio.h>
- #include <unistd.h>
- #include <signal.h>
- #include <sys/time.h>
- void alarm_handler(int signo)
- {
- printf("Timer hit!\n");
- }
- void foo(void)
- {
- struct itimerval delay;
- int ret;
- signal(SIGALRM, alarm_handler);
- delay.it_value.tv_sec = 1;
- delay.it_value.tv_usec = 0;
- delay.it_interval.tv_sec = 1;
- delay.it_interval.tv_usec = 0;
- ret = setitimer(ITIMER_REAL, &delay, NULL);
- if (ret) {
- perror("setitimer");
- return;
- }
- while (1);
- }
- int main(void)
- {
- foo();
- return 0;
- }