| 方案 | 精度 | 依賴 | 跨平台 | 適用場景 |
|---|---|---|---|---|
C time.h + strftime | 秒 | 標準庫 | ✅ 完全 | 日誌、時間戳、跨平台 |
Windows GetLocalTime | 毫秒 | Windows API | ❌ 僅 Windows | 高精度本地時間、文件時間戳 |
MFC CTime::GetCurrentTime | 秒 | MFC | ❌ 僅 MFC | MFC 專案快速格式化 |
C++11 chrono + system_clock | 納秒 | 標準庫 | ✅ 完全 | 現代 C++、高精度計時、跨平台 |
system("time") | 秒 + 交互 | Shell | ⚠️ 僅 Windows (命令不同) | 調試、修改系統時間 (需管理員) |
time.h) - 跨平台基石
#include
#include
int main() {
time_t now = time(NULL); // 秒級時間戳 (1970-01-01 起秒數)
struct tm *local = localtime(&now); // 轉換為本地時間結構
char buf[64];
strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %A 第%j周 %Z", local);
// %Y年 %m月 %d日 %H時 %M分 %S秒 %A星期名 %j年內天數 %Z時區
puts(buf);
// 解析字符串時間
struct tm tm = {0};
strptime("2023-12-25 10:30:00", "%Y-%m-%d %H:%M:%S", &tm);
time_t t = mktime(&tm);
return 0;
}
GetLocalTime) - 毫秒精度
#include
#include
int main() {
SYSTEMTIME st;
GetLocalTime(&st); // 獲取本地時間 (結構體字段精確到毫秒)
printf("%04d-%02d-%02d %02d:%02d:%02d.%03d 星期%d\n",
st.wYear, st.wMonth, st.wDay,
st.wHour, st.wMinute, st.wSecond, st.wMilliseconds,
st.wDayOfWeek); // 0=周日
// 設置系統時間 (需管理員權限)
// SYSTEMTIME stNew = {2024, 1, 1, 0, 0, 0, 0, 0};
// SetLocalTime(&stNew);
return 0;
}
CTime - 框架集成
#include // 或 afx.h
void CMyDlg::OnUpdateTime() {
CTime now = CTime::GetCurrentTime();
CString str = now.Format(_T("%H:%M:%S")); // 格式化字符串
SetDlgItemText(IDC_EDIT_TIME, str);
// 也可用 CTimeSpan 計算差值
CTime start(2023, 1, 1, 0, 0, 0);
CTimeSpan diff = now - start;
TRACE(_T("距離2023年已過 %d 天\n"), diff.GetDays());
}
- 現代標準
#include
#include
#include
#include
int main() {
using namespace std::chrono;
// 1. 當前時間點 (系統時鐘)
auto now = system_clock::now();
// 2. 轉 time_t (秒級) 用於格式化
time_t tt = system_clock::to_time_t(now);
std::tm local_tm = *std::localtime(&tt);
// 3. 獲取毫秒/微秒/納秒部分
auto ms = duration_cast(now.time_since_epoch()) % 1000;
auto us = duration_cast(now.time_since_epoch()) % 1000000;
// 4. 格式化輸出
std::cout << std::put_time(&local_tm, "%Y-%m-%d %H:%M:%S")
<< '.' << std::setfill('0') << std::setw(3) << ms.count()
<< " (us: " << us.count() % 1000 << ")\n";
// 5. 高精度計時 (steady_clock)
auto start = steady_clock::now();
// ... 執行代碼 ...
auto end = steady_clock::now();
auto elapsed = duration_cast(end - start);
std::cout << "Elapsed: " << elapsed.count() << " us\n";
return 0;
}
system("time") - Shell 交互 (不推薦生產用)
#include
#include
int main() {
system("time"); // 彈出命令行輸入新時間 (需管理員)
// 僅適合調試/教學,不適用於程序內部獲取時間
return 0;
}
FILETIME / std::filesystem)
// Windows FILETIME (1601-01-01 起 100ns 間隔)
FILETIME ft;
GetSystemTimeAsFileTime(&ft); // UTC
// 轉換為 SYSTEMTIME
SYSTEMTIME st; FileTimeToSystemTime(&ft, &st);
// C++17 filesystem (跨平台)
#include
namespace fs = std::filesystem;
auto ftime = fs::last_write_time("test.txt");
auto sctp = std::chrono::clock_cast(ftime);
std::time_t tt = std::chrono::system_clock::to_time_t(sctp);
std::cout << std::ctime(&tt);
localtime 返回靜態緩衝區指針 → 多線程不安全。用 localtime_r (POSIX) / localtime_s (C11/MSVC) 或 C++11 chrono。time_t 2038 年問題 (32位系統) → 64位編譯或用 int64_t 存儲毫秒時間戳。GetLocalTime 返回本地時間,GetSystemTime 返回 UTC → 混淆導致時區錯誤。CTime 範圍限制 (1970-2038 早期版本) → 新版 MFC 支持更廣,但跨平台首選 chrono。system("time") 安全風險 (命令注入)、彈窗干擾、不可移植 → 禁用。std::chrono (C++11/17/20)。GetLocalTime / GetSystemTime。CTime 格式化便利,內部可轉 chrono 計算。time.h + strftime。QueryPerformanceCounter / steady_clock。VC 獲取時間五大方案各有優勢:C 標準庫跨平台、Windows API 毫秒精度、MFC 封裝便利、C++11 chrono 現代標準、system 命令交互。生產代碼首選 chrono (現代) 或 GetLocalTime (Windows 專用)。注意線程安全、時區區分、2038 年問題。文件時間戳用 FILETIME 或 C++17 filesystem。