首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

使用 C 標準庫獲取本地時間 (struct tm 與 localtime 完整指南)

     編輯:關於C語言

核心結構體 struct tm

定義於 <time.h>,分解時間為人類可讀欄位:

[c]
struct tm {
    int tm_sec;     // 秒 [0, 60] (含閏秒)
    int tm_min;     // 分 [0, 59]
    int tm_hour;    // 時 [0, 23]
    int tm_mday;    // 日 [1, 31]
    int tm_mon;     // 月 [0, 11] (0=一月)
    int tm_year;    // 年 (從 1900 起算)
    int tm_wday;    // 星期 [0, 6] (0=週日)
    int tm_yday;    // 年內天數 [0, 365]
    int tm_isdst;   // 夏令時標誌
    long tm_gmtoff; // UTC 偏移秒 (BSD/GNU 擴展)
    char *tm_zone;  // 時區縮寫 (BSD/GNU 擴展)
};

獲取本地時間標準流程

[c]
#include 
#include  // gettimeofday

struct tm* get_local_time() {
    struct timeval tv;
    gettimeofday(&tv, NULL);        // 取得微秒級時間戳
    time_t now = tv.tv_sec;         // 秒部分
    struct tm *local = localtime(&now); // 轉換為本地時間 (靜態緩衝區,非執行緒安全)
    
    // 手動補充毫秒 (標準 tm 無毫秒欄位,借用 tm_gmtoff 或自擴展)
    // local->tm_gmtoff = tv.tv_usec / 1000; // 注意:tm_gmtoff 原意是 UTC 偏移,此處僅為演示
    
    // 調整為人類習慣表示
    local->tm_year += 1900; // 實際年份
    local->tm_mon  += 1;    // 1-12 月
    
    return local;
}

Objective-C / iOS 專用封裝 (參考原文)

[objc]
- (struct tm*)getTime {
    struct timeval ticks;
    gettimeofday(&ticks, nil);
    time_t now;
    time(&now);
    struct tm* timeNow = localtime(&now);
    
    timeNow->tm_gmtoff = ticks.tv_usec / 1000; // 存毫秒 (非標準用法)
    timeNow->tm_year += 1900;
    timeNow->tm_mon  += 1;
    return timeNow;
}

關鍵注意事項

  1. 執行緒安全:localtime 返回指向**靜態內部緩衝區**的指標,多執行緒並發調用會互相覆蓋。解決方案:
    • C11 localtime_s (Windows) / localtime_r (POSIX) — 需自行提供 struct tm 緩衝區。
    • 或在關鍵區加鎖。
  2. 時區與夏令時:localtime 依賴系統時區設定 (TZ 環境變數、/etc/localtime)。嵌入式裝置需確保時區數據正確。
  3. 年份/月份偏移:tm_year 從 1900 起算,tm_mon 0-based,**輸出/存儲前必須修正**,否則極易產生「2024 年變 124 年」、「1 月變 0 月」Bug。
  4. 毫秒/微秒精度:標準 struct tm 無亞秒欄位。常見做法:
    • 自定結構體包含 int tm_msec。
    • 或使用 struct timespec / struct timeval 並行傳遞。
  5. 效率對比:原文提到 C 庫函數比 Objective-C NSDate 快 3-4 倍,屬實。NSDate 涉及物件分配、保留/釋放、格式化器開銷;C 函數僅系統調用 + 簡單運算。

格式化輸出範例

[c]
char buf[64];
struct tm *t = get_local_time();
strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", t);
printf("Local time: %s\n", buf);
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved