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

C語言時間處理函數詳解:time_t 與 struct tm 互轉與格式化輸出

     編輯:Java 相關知識

前言

在 C 語言開發中,時間處理是基礎且高頻的需求。標準庫 <time.h> 提供了 time_t、struct tm 兩種核心類型,以及一系列轉換與格式化函數。本文系統梳理它們的關係、常用函數用法與實戰技巧,幫助開發者快速掌握時間獲取、計算與顯示。

核心數據類型

1. time_t —— 時間戳

  • 本質是長整型(通常為 64 位),表示從 1970-01-01 00:00:00 UTC 到現在經過的秒數。
  • 獲取方式:time_t now = time(NULL); 或 time(&now);
  • 適用場景:時間差計算、隨機種子生成(srand((unsigned)time(NULL)))、簡單的時間存儲。

2. struct tm —— 分量時間結構

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*)自定義格式化輸出最靈活、線程安全,推薦生產環境使用

實戰代碼示例

1. 獲取當前時間並格式化輸出

#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;
}

2. 時間差計算(如:統計代碼執行耗時)

time_t start = time(NULL);
// ... 執行耗時操作 ...
time_t end = time(NULL);
double diff = difftime(end, start);  // 返回 double 秒數
printf("耗時: %.2f 秒\n", diff);

3. 線程安全寫法(POSIX 環境)

struct tm result;
localtime_r(&now, &result);  // Linux/Unix 專用
// Windows 使用 localtime_s(&result, &now);
char buf[64];
strftime(buf, sizeof(buf), "%F %T", &result);

常見陷阱與最佳實踐

  1. 靜態緩衝區共享:localtime/gmtime/asctime/ctime 返回的指針指向進程級靜態內存,多線程調用會互相覆蓋。生產代碼請改用 localtime_r / localtime_s + strftime。
  2. 月份與年份偏移:tm_mon 0-11,tm_year 為距 1900 的偏移,輸出時務必 +1、+1900。
  3. 時區影響:time_t 本身不帶時區,localtime 依賴環境變量 TZ,跨時區部署時需顯式設置或使用 UTC。
  4. Y2038 問題:32 位系統 time_t 為有符號 32 位整數,最晚表示到 2038-01-19。現代 64 位系統已解決,但嵌入式開發仍需注意。

總結

掌握 time_t(計算、存儲)與 struct tm(顯示、分量操作)的轉換鏈路,熟練使用 strftime 進行自定義格式化,並注意線程安全與時區問題,即可應對絕大多數 C 語言時間處理場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved