Windows API GetSystemTime/SetSystemTime 可存取系統即時時鐘。SYSTEMTIME 結構包含 wDayOfWeek 欄位 (0=星期日 ... 6=星期六)。我們可暫時修改系統時間為目標日期,讀取 wDayOfWeek,再還原系統時間,即得星期幾。此法避免自行實作 Zeller 公式等演算法。
void __fastcall TForm1::Button1Click(TObject *Sender)
{
const char* WeekName[7] = {
"星期日", "星期一", "星期二", "星期三",
"星期四", "星期五", "星期六"
};
SYSTEMTIME Now, Tmp;
GetSystemTime(&Now); // 備份目前系統時間
// 設定欲查詢的目標日期時間 (任意合法值)
Tmp.wYear = 2024; // 年
Tmp.wMonth = 12; // 月
Tmp.wDay = 25; // 日
Tmp.wHour = 12; // 時 (建議非 0 避免邊界問題)
Tmp.wMinute = 0;
Tmp.wSecond = 0;
Tmp.wMilliseconds = 0;
// 嘗試設定系統時間 (需管理員權限)
if (SetSystemTime(&Tmp)) {
GetSystemTime(&Tmp); // 讀回系統時間 (含 wDayOfWeek)
ShowMessage(WeekName[Tmp.wDayOfWeek]);
} else {
DWORD err = GetLastError();
ShowMessage("設定失敗,錯誤碼: " + IntToStr(err) +
(err == 87 ? " (參數錯誤,檢查日期合法性)" : ""));
}
SetSystemTime(&Now); // 還原系統時間 (需管理員權限)
}
| 項目 | 說明 |
|---|---|
SetSystemTime 需 管理員權限 (Vista+ UAC)。普通使用者執行會失敗 (ERROR_ACCESS_DENIED = 5)。 | |
| 暫時修改系統時間會影響所有執行中程式的時間相關操作 (日誌、定時器、SSL 憑證驗證等)。極不建議在生產環境使用。 | |
傳入非法日期 (如 2 月 30 日) 會導致 SetSystemTime 失敗,回傳 ERROR_INVALID_PARAMETER (87)。 | |
| 多執行緒同時呼叫會互相干擾系統時間。 | |
SYSTEMTIME 為 UTC 時間,wDayOfWeek 同 UTC。若需本地時區星期,請用 GetLocalTime/SetLocalTime (同樣需管理員權限)。 |
int DayOfWeek(int year, int month, int day) {
if (month < 3) { month += 12; year--; }
int c = year / 100;
int y = year % 100;
int w = (y + y/4 + c/4 - 2*c + 26*(month+1)/10 + day - 1) % 7;
return (w + 7) % 7; // 0=週日 ... 6=週六
}
<chrono> (現代標準庫)
#include
#include
int DayOfWeekModern(int y, int m, int d) {
using namespace std::chrono;
auto dp = year_month_day{year(y), month(m), day(d)};
auto wd = weekday{dp};
return (static_cast(wd) + 6) % 7; // 0=週日
}
GetDateFormat (無需改系統時間)
int GetDayOfWeekAPI(int year, int month, int day) {
SYSTEMTIME st = {0};
st.wYear = year; st.wMonth = month; st.wDay = day;
char buf[16];
GetDateFormatA(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, "ddd", buf, 16);
// buf 為 "Sun", "Mon" 等,需映射表轉數字
// 較繁瑣,不推薦
}
SetSystemTime 技巧展示 Windows 日期時間結構與系統服務互動,理解 SYSTEMTIME.wDayOfWeek 來源。<chrono>、Boost.Date_Time 或 Howard Hinnant 的 date.h 單一標頭庫,皆為純計算、執行緒安全、無權限需求、跨平台。