1. 前言
在使用 C 語言開發程式時,經常需要處理日期與時間資訊。其中最常用的函式之一就是 localtime
。這個函式在取得考慮時區的本地時間時非常方便。然而,對於初學者而言,其用法與注意事項可能不太容易理解。
本文將從 localtime
函式的基本用法到進階應用,再到需要注意的重點,進行淺顯易懂的解說。為了讓初學者也能理解,我們會搭配具體範例進行說明,請務必閱讀到最後。
2. 什麼是 localtime
函式?
localtime
函式概述
localtime
是 C 語言標準函式庫中用於時間處理的函式之一,廣泛應用於 POSIX 與 Windows 等環境。它可以將一個代表時間戳的 time_t
型別轉換為考慮時區的本地時間(struct tm
型別)。
time_t
與 struct tm
的關係
在 C 語言中,處理時間時主要會使用兩種型別:
time_t
型別:表示自 1970 年 1 月 1 日 0 時 0 分 0 秒(UTC)以來經過的秒數。struct tm
型別:將時間資訊分解儲存的結構體,包含年、月、日、時、分、秒等詳細資料。
localtime
負責在這兩種型別之間進行轉換。
函式原型
#include <time.h>
struct tm *localtime(const time_t *timer);
此函式會根據指標 timer
指向的 time_t
值,返回對應的本地時間。
3. localtime
的基本用法
基本程式範例
以下示範如何取得目前時間並轉換為本地時間:
#include <time.h>
#include <stdio.h>
int main() {
time_t t = time(NULL); // 取得目前時間
struct tm *local = localtime(&t); // 轉換為本地時間
printf("目前時間: %02d:%02d:%02d\n",
local->tm_hour, local->tm_min, local->tm_sec);
return 0;
}
程式解說
- 使用
time(NULL)
取得目前的 UNIX 時間戳。 - 透過
localtime
將time_t
轉換為struct tm
的本地時間。 - 透過
struct tm
的成員(如tm_hour
、tm_min
、tm_sec
)分別取得時間資訊。
執行結果範例
目前時間: 14:30:15
重點
localtime
返回的是靜態配置的結構體指標,重複呼叫時資料會被覆蓋,後續會提到解決方法。
4. 進階應用:格式化日期時間
使用 strftime
改變輸出格式
若要以特定格式輸出本地時間,可使用 strftime
函式。
以下範例將日期時間輸出為「YYYY-MM-DD HH:MM:SS」格式:
#include <time.h>
#include <stdio.h>
int main() {
time_t t = time(NULL);
struct tm *local = localtime(&t);
char buffer[80];
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", local);
printf("格式化時間: %s\n", buffer);
return 0;
}
輸出範例
格式化時間: 2024-11-17 14:30:15
常用格式化符號
%Y
:西元年(4 位數)%m
:月份(2 位數)%d
:日期(2 位數)%H
:小時(24 小時制)%M
:分鐘%S
:秒

5. 注意事項與最佳實踐
執行緒安全性問題
localtime
並非執行緒安全(thread-safe),因為它返回的指標指向靜態記憶體區域,呼叫時會被覆蓋,導致多執行緒環境下可能出現不可預期的行為。
解決方法:使用 localtime_r
在 POSIX 系統中,可使用執行緒安全的 localtime_r
,它會使用呼叫端提供的 struct tm
儲存結果。
範例:localtime_r
的使用
#include <time.h>
#include <stdio.h>
int main() {
time_t t = time(NULL);
struct tm local;
if (localtime_r(&t, &local) != NULL) {
printf("目前時間: %02d:%02d:%02d\n",
local.tm_hour, local.tm_min, local.tm_sec);
} else {
perror("localtime_r error");
}
return 0;
}
在 Windows 中使用 localtime_s
Windows 環境提供了 localtime_s
作為執行緒安全版本。
範例:localtime_s
的使用
#include <time.h>
#include <stdio.h>
int main() {
time_t t = time(NULL);
struct tm local;
if (localtime_s(&local, &t) == 0) {
printf("目前時間: %02d:%02d:%02d\n",
local.tm_hour, local.tm_min, local.tm_sec);
} else {
perror("localtime_s error");
}
return 0;
}
記憶體管理注意事項
localtime
返回的指標指向靜態記憶體,不需要手動釋放。但在再次呼叫 localtime
或相關函式時資料會被覆蓋,因此若需長期保存結果,應複製到其他變數中。
6. FAQ 常見問題與解答
Q1: 為什麼 localtime
的返回值會是 NULL
?
A:
主要原因如下:
- 傳入的
time_t
值無效(例如負數)。 - 系統記憶體不足,導致處理失敗。
解決方法:
確認 time_t
值的正確性,並在程式中加入錯誤處理。
if (localtime(&t) == NULL) {
perror("localtime failed");
}
Q2: gmtime
與 localtime
有什麼差別?
A:
localtime
:返回考慮時區的本地時間。gmtime
:返回基於 UTC(協調世界時)的時間,不考慮時區。
Q3: 如何在多執行緒環境安全地使用 localtime
?
A:
在多執行緒環境中,請使用 localtime_r
(POSIX 系統)或 localtime_s
(Windows 系統),避免靜態記憶體覆蓋問題。
7. 相關函式簡介
gmtime
函式
gmtime
與 localtime
類似,但它返回的是 UTC 時間資訊,忽略時區設定。範例如下:
#include <time.h>
#include <stdio.h>
int main() {
time_t t = time(NULL);
struct tm *utc = gmtime(&t);
printf("UTC 時間: %02d:%02d:%02d\n",
utc->tm_hour, utc->tm_min, utc->tm_sec);
return 0;
}
mktime
函式
mktime
可將 struct tm
型別轉回 time_t
,也就是將本地時間轉換成 UNIX 時間戳。
範例:使用 mktime
#include <time.h>
#include <stdio.h>
int main() {
struct tm local = {0};
local.tm_year = 2024 - 1900; // 年份需減去 1900
local.tm_mon = 10; // 月份(0~11)
local.tm_mday = 17; // 日期
time_t t = mktime(&local);
if (t != -1) {
printf("UNIX 時間戳: %ld\n", t);
} else {
perror("mktime failed");
}
return 0;
}
8. 總結
本文詳細介紹了 C 語言的 localtime
函式,包括基本用法、進階應用與注意事項,重點如下:
localtime
概述:方便取得本地時間的函式。- 注意事項:非執行緒安全,建議使用
localtime_r
或localtime_s
。 - 進階應用:透過
strftime
改變輸出格式。 - FAQ:常見問題原因與解決方法。
透過本文,您應該能夠正確運用 localtime
,並在 C 語言中高效處理日期與時間。同時,建議搭配 gmtime
與 mktime
等相關函式使用,以滿足更多情境需求。