在 C 語言開發中,時間處理是基礎且高頻的需求。標準庫 <time.h> 提供了 time_t、struct tm 兩種核心類型,以及一系列轉換與格式化函數。本文系統梳理它們的關係、常用函數用法與實戰技巧,幫助開發者快速掌握時間獲取、計算與顯示。
time_t now = time(NULL); 或 time(&now);srand((unsigned)time(NULL)))、簡單的時間存儲。struct tm {
int tm_sec; // 秒 [0,59]
int tm_min; // 分 [0,59]
int tm_hour; // 時 [0,23]
int tm_mday; // 日 [1,31]
int tm_mon; // 月 [0,11] 0=一月
int tm_year; // 年 實際年份 = tm_year + 1900
int tm_wday; // 星期 [0,6] 0=星期日
int tm_yday; // 年內天數 [0,365]
int tm_isdst; // 夏令時標誌
};
注意:tm_mon 從 0 開始,tm_year 需加 1900,這是新手最易踩的坑。
| 函數 | 作用 | 備註 |
|---|---|---|
localtime(time_t*) | 時間戳 → 本地時間 struct tm* | 返回靜態內存指針,非線程安全 |
gmtime(time_t*) | 時間戳 → UTC 時間 struct tm* | 同樣返回靜態指針 |
mktime(struct tm*) | struct tm → time_t | 會自動修正超範圍字段(如月份 13 → 翌年 1 月) |
asctime(struct tm*) | struct tm → 固定格式字符串 | 格式:"Tue Jan 6 13:53:16 2015\n" |
ctime(time_t*) | time_t → 固定格式字符串 | 等價於 asctime(localtime(t)) |
strftime(char*, size_t, const char*, struct tm*) | 自定義格式化輸出 | 最靈活、線程安全,推薦生產環境使用 |
#include <stdio.h>
#include <time.h>
int main() {
time_t now = time(NULL);
struct tm *local = localtime(&now);
// 方式一:固定格式
printf("ctime: %s", ctime(&now));
printf("asctime: %s", asctime(local));
// 方式二:自定義格式(推薦)
char buf[64];
strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", local);
printf("strftime: %s\n", buf);
// 方式三:手動拼裝(教學用)
printf("手動: %d-%02d-%02d %02d:%02d:%02d\n",
local->tm_year + 1900, local->tm_mon + 1, local->tm_mday,
local->tm_hour, local->tm_min, local->tm_sec);
return 0;
}
time_t start = time(NULL);
// ... 執行耗時操作 ...
time_t end = time(NULL);
double diff = difftime(end, start); // 返回 double 秒數
printf("耗時: %.2f 秒\n", diff);
struct tm result;
localtime_r(&now, &result); // Linux/Unix 專用
// Windows 使用 localtime_s(&result, &now);
char buf[64];
strftime(buf, sizeof(buf), "%F %T", &result);
localtime/gmtime/asctime/ctime 返回的指針指向進程級靜態內存,多線程調用會互相覆蓋。生產代碼請改用 localtime_r / localtime_s + strftime。tm_mon 0-11,tm_year 為距 1900 的偏移,輸出時務必 +1、+1900。time_t 本身不帶時區,localtime 依賴環境變量 TZ,跨時區部署時需顯式設置或使用 UTC。time_t 為有符號 32 位整數,最晚表示到 2038-01-19。現代 64 位系統已解決,但嵌入式開發仍需注意。掌握 time_t(計算、存儲)與 struct tm(顯示、分量操作)的轉換鏈路,熟練使用 strftime 進行自定義格式化,並注意線程安全與時區問題,即可應對絕大多數 C 語言時間處理場景。