由UNIX內核提供的基本時間服務是計算自國際標準時間公元1970年1月1日00:00:00以來經過的秒數。這種秒數是以數據類型time_t表示的。我們稱它們為日歷時間。日歷時間包括時間和日期。UNIX在這方面與其他操作系統的區別是:(a)以國際標準時間而非本地時間計時;(b)可自動進行轉換,例如變換到夏時制;(c)將時間和日期作為一個量值保存。
time函數返回當前時間和日期:
#include <time.h>time_t time( time_t *calptr );返回值:若成功則返回時間值,若出錯則返回-1
時間值總是作為函數值返回。如果參數不為空,則時間值也存放在由calptr指向的單元內。
在系統V派生的系統中,調用stime(2)函數,在BSD派生的系統中,則調用settimeofday(2),用于對內核中的當前時間設置初始值。
與time函數相比,gettiimeofday提供了更高的分辨率(最高為微秒級)。這對于某些應用很重要。
#include <sys/time.h>int gettimeofday( struct timeval *restrict tp, void *restrict tzp );返回值:總是返回0
該函數作為XSI擴展定義在Single UNIX Specification中,tzp的唯一合法值是NULL,其他值則將產生不確定的結果。
gettimeofday函數將當前時間存放在tp指向的timeval結構中,而該結構存儲秒和微秒。
struct timeval { time_t tv_sec; /* seconds */ long tv_usec; /* microseconds */};
一旦取得這種以秒計的整型時間值后,通常要調用另一個時間函數將其轉換為人們可讀的時間和日期。圖6-1說明了各種時間函數之間的關系。(圖中用虛線表示的四個函數localtime、mktime、ctime和strftime都受到環境變量TZ的影響:如果定義了TZ,則這些函數將使用其值以代替系統默認時區。如果TZ定義為空串(即TZ=),則使用國際標準時間UTC。)
圖6-1 各個時間函數之間的關系
兩個函數localtime和gmtime將日歷時間轉換成以年、月、日、時、分、秒、周日表示的時間,并將這些存放在一個tm結構中。
struct tm { /* a broken-down time */ int tm_sec; /* seconds after the minute: [0 - 60] */ int tm_min; /* minutes after the hour: [0 - 59] */ int tm_hour; /* hours after midnight: [0 - 23] */ int tm_mday; /* day of the month: [1 - 31] */ int tm_mon; /* months since January: [0 - 11] */ int tm_year; /* years since 1900 */ int tm_wday; /* days since Sunday: [0 - 6] */ int tm_yday; /* days since January: [0 - 365] */ int tm_isdst; /* daylight saving time flag: [<0, =0, >0] */};
關于上面結構的最后一項tm_isdst(夏時制標志)可參考:http://blog.163.com/caoguoqiang_dlut/blog/static/1065891422011321115144181/
秒可以超過59的理由是可以表示潤秒。注意,除月日字段,其他字段的值都以0開始。如果夏時制生效,則夏時制標志為正;如果為非夏時制時間,則該標志值為0;如果此信息不可用,則其值為負。
#include <time.h>struct tm *gmtime( const time_t *calptr );struct tm *localtime( const time_t *calptr );兩個函數返回值:指向tm結構的指針。
localtime和gmtime之間的區別是:localtime將日歷時間轉換成本地時間(考慮到本地時間和夏時制標志),而gmtime則將日歷時間轉換成國際標準時間的年、月、日、時、分、秒、周日。
函數mktime以本地時間的年、月、日等作為參數,將其轉換成time_t值。
#include <time.h>time_t mktime( struct tm *tmptr );返回值:若成功則返回日歷時間,若出錯則返回-1
asctime和ctime函數產生大家都熟悉的26字節的字符串,這與date(1)命令的系統默認輸出形式類似,例如:
Mon Jan 6 01:59:18 PST 2014
#include <time.h>char *asctime( const struct tm *tmptr );char *ctime( const time_t *calptr );兩個函數返回值:指向以null結尾的字符串的指針
asctime的參數是指向年、月、日等字符串的指針,而ctime的參數則是指向日歷時間的指針。
最后一個時間函數是strftime,它是非常復雜的類似于PRintf的時間值函數。
#include <time.h>size_t strftiime( char *restrict buf, size_t maxsize, const char *restrict format, const struct tm *restrict tmptr );返回值:若有空間則返回存入數組的字符數,否則返回0
最后一個參數是要格式化的時間值,由一個指向tm結構的指針指定。格式化結果存放在一個長度為maxsize個字符的buf數組中,如果buf長度足以存放格式化結果及一個null終止符,則該函數返回在buf中存放的字符數(不包括null終止符),否則該函數返回0。
format參數控制時間值的格式。如同printf函數一樣,轉換說明的形式是百分號之后跟一個特定字符。format中的其他字符則按原樣輸出。兩個連續的百分號在輸出中產生一個百分號。與printf函數不同的是,每個轉換說明產生一個不同的定長輸出字符串,在format字符串中沒有字段寬度修飾符。
下表中列出了部分轉換說明,更詳細的可man strftime查看。
本篇博文內容摘自《UNIX環境高級編程》(第二版),僅作個人學習記錄所用。關于本書可參考:http://www.apuebook.com/。
新聞熱點
疑難解答