警告 C26861
已修改日期時間物件的
var
欄位,而不需進行適當的閏年檢查:expr
此規則已在 Visual Studio 2022 17.8 中新增。
備註
在公曆中,每年只有四分之一的可分割是一個閏年,除了100年完全可見的年份。 百年也是閏年,如果他們完全被400分分。
當軟體不考慮這個閏年邏輯,或使用有缺陷的邏輯時,就會發生閏年錯誤。 可能會影響受影響系統的可靠性、可用性,甚至是安全性。
不安全地在日期時間物件的年、月或日欄位中新增或減去某些數位,而不考慮閏年。 此計算通常會執行,以判斷憑證的到期日,例如。 在許多日期,天真的計算可能會產生所需的結果。 不過,當結果為 2 月 29 日(閏日)且年份不是閏年時,結果會無效。
例如,將一年新增至 2020-01-31 會產生 2021-01-31。 但是,將一年新增至 2020-02-29 會產生 2021-02-29,這不是有效的日期,因為 2021 年不是閏年。
在操作代表日期值的變數時請小心。 正確處理閏年和閏天,或使用可安全地處理日期算術的 API 或連結庫。
程式代碼分析名稱: DATETIME_MANIPULATION_WITHOUT_LEAPYEAR_CHECK
範例
下列程式代碼會藉由遞增代表系統時間之日期時間物件的年份欄位,將系統時間往前移一年。 不過,如果修改前的日期是 2 月 29 日,它可能會產生無效的日期時間對象,因為明年不是閏年:
SYSTEMTIME st;
GetSystemTime(&st);
st.wYear++; // warning C26861
若要避免因為閏年而建立無效的日期時間物件,請檢查產生的日期是否仍然有效,並進行必要的調整,使其有效,如下列範例所示:
SYSTEMTIME st;
GetSystemTime(&st);
st.wYear++;
if (st.wMonth == 2 && st.wDay == 29)
{
// move back a day when landing on Feb 29 in a non-leap year
bool isLeapYear = st.wYear % 4 == 0 && (st.wYear % 100 != 0 || st.wYear % 400 == 0);
if (!isLeapYear)
{
st.wDay = 28;
}
}
啟發學習法
目前,此規則只會辨識 Windows SYSTEMTIME
結構與 C tm
結構。
此規則會採用簡化的啟發學習法來尋找潛在的風險變更,並報告警告,除非有適當的閏年或閏日檢查。 它不會嘗試驗證修改日期時間物件是否正確執行閏年或閏日檢查。
此規則是加入加入規則,這表示程式代碼分析應該使用規則集檔案,而且規則應該明確包含在規則集檔案中,並啟用規則以套用規則集檔案。 如需建立程式代碼分析自定義規則集的詳細資訊,請參閱: 使用規則集指定要 C++
執行的規則。