time.h是C標準函數庫中獲取時間與日期、對時間與日期數據操作及格式化的頭文件。
表示時間的三種數據類型
- 日曆時間(Calendar Time),是從一個標準時間點(epoch)到現在的時間經過的秒數,不包括插入閏秒對時間的調整。開始計時的標準時間點,各種編譯器一般使用UTC 1970-01-01 00:00:00。日曆時間用數據類型
time_t
表示。[1]:20time_t
類型實際上一般是32位整數類型,因此表示的時間不能晚於UTC 2038-01-18 19:14:07。為此,某些編譯器引入了64位甚至更長的整型來保存日曆時間,如Visual C++支持__time64_t
數據類型,通過_time64()
函數獲取日曆時間,可支持到UTC 3001-01-01 00:00:00的時間。
- 處理器時間(Processor Time),也被稱為CPU時間(CPU Time),用以度量進程使用的CPU資源。處理器時間以時鐘滴答數(Clock Tick)計算,通常從進程啟動開始計時,因此這是相對時間。時鐘滴答數用系統基本數據類型
clock_t
來表示,每秒鐘包含CLOCKS_PER_SEC
(time.h中定義的常量,一般為1000)個時鐘滴答,也可使用sysconf
函數得到每秒的時鐘滴答數。clock_t
類型一般是32位整數類型。[1]:20
- 分解時間(broken-down time),用結構數據類型
tm
表示,tm
包含下列結構成員:
成員 |
描述
|
int tm_hour |
小時 (0 – 23)
|
int tm_isdst |
夏令時啟用 (> 0)、禁用 (= 0)、未知 (< 0)
|
int tm_mday |
一月中的哪一天 (1 – 31)
|
int tm_min |
分 (0 – 59)
|
int tm_mon |
月 (0 – 11, 0 = 一月)
|
int tm_sec |
秒 (0 – 60, 60 = 閏秒)
|
int tm_wday |
一周中的哪一天 (0 – 6, 0 = 周日)
|
int tm_yday |
一年中的哪一天 (0 – 365)
|
int tm_year |
1900 以來的年數
|
從計算機系統時鐘獲得時間的方法
time_t time(time_t* timer)
- 得到從標準計時點(一般是UTC 1970年1月1日午夜)到當前時間的秒數。
- 得到從進程啟動到此次函數調用的累計的時鐘滴答數。
Windows API提供了更為精確的GetLocalTime()獲取毫秒級的日曆時間;QueryPerformanceCounter和QueryPerformanceFrequency兩個函數獲取高於1毫秒的精度。
三種時間日期數據類型的轉換函數
struct tm* gmtime(const time_t* timer)
- 從日曆時間
time_t
到分解時間tm
(世界協調時UTC)的轉換。函數返回的是一個靜態分配的tm
結構存儲空間,該存儲空間被gmtime
, localtime
與ctime
函數所共用. 這些函數的每一次調用會覆蓋這塊tm
結構存儲空間的內容。
struct tm* gmtime_r(const time_t* timer, struct tm* result)
- 該函數是
gmtime
函數的線程安全版本.
struct tm* localtime(const time_t* timer)
- 從日曆時間
time_t
到分解時間tm
的轉換,即結果數據已經調整到本地時區與夏令時。
time_t mktime(struct tm* ptm)
- 從基於本地時區(與夏令時)的分解時間
tm
到日曆時間time_t
的轉換。忽略tm_wday與tm_yday的輸入值。如果tm_isdst不確定則輸入設為-1。其它各輸入域的值可以任意設定,輸出時被規範化到正確範圍。例如,想要計算2012年的第200天的日期,設為1月200日,函數會輸出正確的結果
time_t timegm(struct tm* brokentime)
- 從分解時間
tm
(被視作UTC時間,不考慮本地時區設置)到日曆時間time_t
的轉換。該函數較少被使用。
時間日期數據的格式化函數
char *asctime(const struct tm* tmptr)
- 把分解時間
tm
輸出到字符串,結果的格式為"Www Mmm dd hh:mm:ss yyyy",即「周幾 月份數 日數 小時數:分鐘數:秒鐘數 年份數」。函數返回的字符串為靜態分配,長度不大於26,與ctime
函數共用。函數的每次調用將覆蓋該字符串內容。
char* ctime(const time_t* timer)
- 把日曆時間
time_t timer
輸出到字符串,輸出格式與asctime
函數一樣.
size_t strftime(char* s, size_t n, const char* format, const struct tm* tptr)
- 把分解時間
tm
轉換為自定義格式的字符串,類似於常見的字符串格式輸出函數sprintf
。例如:strftime(buf, 64, "%Y-%m-%d %H:%M:%S", localtime);
char * strptime(const char* buf, const char* format, struct tm* tptr)
strftime
的逆操作,把字符串按照自定義的格式轉換為分解時間tm
。
對時間數據的操作
double difftime(time_t timer2, time_t timer1)
- 比較兩個日曆時間之差。
源代碼示例
打印當前時間到標準輸出流:
# include <stdio.h>
# include <time.h>
int main(void)
{
time_t timer = time(NULL);
printf("ctime is %s\n", ctime(&timer));
return 0;
}
參考文獻
參考來源
外部連結