警告 C26864
日期時間物件的
var
日期欄位已修改,假設每年 365 天沒有適當的閏年檢查:expr
此規則已在 Visual Studio 2022 17.8 中新增。
備註
在公曆中,每年只有四分之一的可分割是一個閏年,除了100年完全可見的年份。 百年也是閏年,如果他們完全被400分分。
當軟體不考慮這個閏年邏輯,或使用有缺陷的邏輯時,就會發生閏年錯誤。 可能會影響受影響系統的可靠性、可用性,甚至是安全性。
當您在代表日期的變數上執行算術運算時,必須考慮閏年。 假設一年是 365 天,這是不安全的。 閏年有 366 天,因為 “閏日” 新增為 2 月的第 29 天。
若要正確前進一年,請判斷時間範圍是否包含閏日,然後使用正確的天數執行計算。 如果年份是直接進階的,最好是在產生的日期上進行適當的閏日檢查。 或者,使用已建立的連結庫例程,正確處理閏年。
程式代碼分析名稱: DATETIME_MANIPULATION_ASSUMING_365_DAYS_WITHOUT_LEAPYEAR_CHECK
範例
下列程式代碼會嘗試取得目前的系統時間、將日期前移一年,方法是將 365 天新增至 day 字段,並調整每個閏年規則的日期。 不過,結果可能不會落在明年的同一個月/日期:
#include <Windows.h>
void foo()
{
SYSTEMTIME st;
GetSystemTime(&st);
// Advance a year by adding 365 days
st.wDay += 365; // C26864
}
若要修正此問題,請直接推進年份欄位,並調整每個閏年規則的日期:
#include <Windows.h>
void foo()
{
SYSTEMTIME st;
GetSystemTime(&st);
st.wYear++; // Advance a year
// Adjust the date
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
結構。
如果日期欄位直接修改為 365 天,則會強制執行此規則。 它不會考慮日期欄位的值是否指派給另一個變數,然後操作,因此可能會錯過對等的錯誤。
此規則是加入加入規則,這表示程式代碼分析應該使用規則集檔案,而且規則應該明確包含在規則集檔案中,並啟用規則以套用規則集檔案。 如需建立程式代碼分析自定義規則集的詳細資訊,請參閱 使用規則集指定要 C++
執行的規則。