參考《C++ 程式設計哲學》風格,實現一個功能完整、介面清晰的 Time 類,支援時間標記、差值計算、日期時間分量提取等常用操作,適用於效能測試、日誌時間戳、定時任務等場景。
<ctime> 介面,提供物件導向 APImark()) 與差值計算 (delta())time_t 為 tm 結構// Cpptime.h
#ifndef CPPTIME_H
#define CPPTIME_H
#include <ctime>
#include <cstring>
class Time {
time_t t; // 原始時間戳
tm local; // 分解後本地時間
char asciiRep[26]; // ASCII 格式化字串緩衝
unsigned char lflag, aflag; // 延遲計算標記
void updateLocal() {
if (!lflag) {
local = *localtime(&t); // 非執行緒安全,單執行緒足夠
lflag = 1;
}
}
void updateAscii() {
if (!aflag) {
updateLocal();
strcpy(asciiRep, asctime(&local)); // 格式: "Www Mmm dd hh:mm:ss yyyy\n"
aflag = 1;
}
}
public:
Time() { mark(); }
void mark() { // 更新時間戳,重置快取
lflag = aflag = 0;
time(&t);
}
const char* ascii() { // 取得格式化字串
updateAscii();
return asciiRep;
}
int delta(const Time* dt) const { // 秒差值
return static_cast<int>(difftime(t, dt->t));
}
// 時間分量存取器 (均觸發 updateLocal)
int daylightSavings() { updateLocal(); return local.tm_isdst; }
int dayOfYear() { updateLocal(); return local.tm_yday; } // 0-365
int dayOfWeek() { updateLocal(); return local.tm_wday; } // 0=Sun
int since1900() { updateLocal(); return local.tm_year; } // 年份-1900
int month() { updateLocal(); return local.tm_mon; } // 0=Jan
int dayOfMonth() { updateLocal(); return local.tm_mday; }
int hour() { updateLocal(); return local.tm_hour; }
int minute() { updateLocal(); return local.tm_min; }
int second() { updateLocal(); return local.tm_sec; }
};
#endif // CPPTIME_H
// Cpptime.cpp
#include "Cpptime.h"
#include <iostream>
using namespace std;
int main() {
Time start;
for (int i = 1; i < 1000; i++) {
cout << i << ' ';
if (i % 10 == 0) cout << endl;
}
Time end;
cout << endl;
cout << "start = " << start.ascii();
cout << "end = " << end.ascii();
cout << "delta = " << end.delta(&start) << " seconds" << endl;
return 0;
}
start = Thu Jan 21 11:27:53 2017
end = Thu Jan 21 11:27:53 2017
delta = 0 seconds
(迴圈太快,秒級精度顯示 0,實際可測量較長操作)
| 特性 | 實現方式 | 優點 |
|---|---|---|
| 延遲計算 | lflag/aflag 標記 | 未呼叫存取器時零開銷 |
| 快取機制 | local/asciiRep 成員 | 同一時間戳多次存取無重複轉換 |
mark() 重置 | 清除標記 + time() | 支援同一物件多次計時 |
difftime 計算差值 | 標準庫函數 | 處理時間戳跨越、閏秒等細節 |
| 非執行緒安全 | localtime 回傳靜態緩衝 | 單執行緒場景足夠;多執行緒需 localtime_r/localtime_s |
<chrono> 庫:std::chrono::high_resolution_clock 納秒精度、型別安全std::format (C++20) 格式化輸出std::localtime (C++23) 或平台專用 localtime_r/localtime_s<chrono> + IANA 時區資料庫這個 Time 類展示了如何將 C 風格時間函數封裝為優雅的 C++ 介面:資料封裝、延遲計算、快取優化、直觀 API。雖然現代專案建議直接使用 <chrono>,但理解這種封裝思維對維護舊代碼、嵌入式開發 (無 <chrono> 支援) 仍有價值。