<time.h> 提供時間處理的核心設施:
long或int64_t)。| 函數 | 功能 | 備註 |
|---|---|---|
time(time_t *t) | 獲取當前日曆時間 | 參數非NULL時也寫入指向位置 |
localtime(const time_t *t) | 轉換為本地時間tm | 返回靜態結構體指針,非線程安全 |
gmtime(const time_t *t) | 轉換為UTC時間tm | 同上 |
mktime(struct tm *tp) | 將tm轉為time_t並修正字段 | 自動處理溢出(如月份>12),返回-1表示錯誤 |
asctime(const struct tm *tp) | 格式化為固定字符串「Www Mmm dd hh:mm:ss yyyy\n\0」 | 返回靜態緩衝區 |
ctime(const time_t *t) | 等價於asctime(localtime(t)) | |
strftime(char *s, size_t max, const char *fmt, const struct tm *tp) | 自定義格式化輸出 | 返回寫入字符數,支持豐富格式符(見下表) |
difftime(time_t t1, time_t t0) | 計算兩時間差(秒),返回double | 處理time_t可能非算術類型的情況 |
clock() | 返回進程CPU時間 | 除以CLOCKS_PER_SEC得秒數 |
| 符號 | 含義 | 示例 |
|---|---|---|
%Y | 完整年份 | 2024 |
%m | 月份(01-12) | 03 |
%d | 日期(01-31) | 15 |
%H | 24制小時(00-23) | 14 |
%M | 分鐘(00-59) | 30 |
%S | 秒(00-60) | 05 |
%F | 等價%Y-%m-%d | 2024-03-15 |
%T | 等價%H:%M:%S | 14:30:05 |
%z | 時區偏移 | +0800 |
%s | Unix時間戳(擴展) | 1710484205 |
mktime自動修正)struct tm dt = *localtime(&now);
dt.tm_mday += 30; // 30天后
dt.tm_mon -= 3; // 3個月前
mktime(&dt); // 自動修正月份/年份溢出
printf("%s", asctime(&dt));
difftime秒精度)// 簡化版:忽略時區/夏令時,假設同一時區午夜
double days_between(struct tm a, struct tm b) {
a.tm_hour = b.tm_hour = 12; // 避免夏令時邊界問題
time_t ta = mktime(&a), tb = mktime(&b);
return fabs(difftime(ta, tb)) / 86400.0;
}
struct timespec start, end;
clock_gettime(CLOCK_MONOTONIC, &start);
// ... 待測代碼 ...
clock_gettime(CLOCK_MONOTONIC, &end);
double elapsed_ms = (end.tv_sec - start.tv_sec) * 1e3 +
(end.tv_nsec - start.tv_nsec) / 1e6;
注意:clock_gettime 需 POSIX(Linux/macOS),Windows 使用 QueryPerformanceCounter。
ANSI C無標準文件時間API,平台方案如下:
stat()/fstat()/lstat() 獲取 st_atime、st_mtime、st_ctime(time_t)。GetFileTime() 獲取 FILETIME(100ns間隔自1601年),需轉換為time_t。<filesystem>:last_write_time(path) 統一跨平台訪問(C++20支持讀/寫)。localtime/gmtime/asctime/ctime 返回靜態緩衝區,多線程必須用 localtime_r/gmtime_r (POSIX) 或 localtime_s (C11 Annex K/Windows)。tm_year = 年份 - 1900,打印時必須 +1900。tm_mon = 0-11,顯示/輸入時 ±1。tm_isdst >0 表示生效,<0 表示未知(讓mktime判斷),mktime會自動調整。跨DST邊界計算差值時,difftime給出真實秒差,mktime修正後的tm反映本地鐘面時間。time_t範圍:32位系統time_t為有符號32位整數,範圍1901-12-13 至 2038-01-19(Y2038問題)。64位系統已遷移至64位time_t,範圍擴展至數十億年。新代碼應假設64位,或使用int64_t顯式存儲時間戳。tzset()/環境變量TZ影響localtime。嵌入式/跨時區應用建議使用 date/tz (Howard Hinnant) 或 boost::local_time / std::chrono::tzdb (C++20)。<chrono>C++11 <chrono> 提供類型安全、精度可控的時間庫;C++20 引入 std::chrono::sys_time、zoned_time、format、parse,實現編譯期檢查、時區感知、無縫格式化,是新項目首選。
// C++20 示例
auto now = std::chrono::system_clock::now();
std::cout << std::format("{:%Y-%m-%d %H:%M:%S %Z}",
std::chrono::zoned_time{std::chrono::current_zone(), now});