共用方式為


警告 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++ 執行的規則。

另請參閱

C6393
C6394
C26861
C26862
C26863