Warnung C26864

Das Tagfeld eines Datums-Uhrzeit-Objekts var wurde geändert, vorausgesetzt, dass 365 Tage pro Jahr ohne ordnungsgemäße Überprüfung des Schaltjahrs: expr

Diese Regel wurde in Visual Studio 2022 17.8 hinzugefügt.

Hinweise

Im gregorianischen Kalender ist jedes Jahr ein Schaltjahr, mit Ausnahme von Jahren, die genau durch 100 divisierbar sind. Die centurialen Jahre sind auch Schaltjahre, wenn sie genau um 400 teilbar sind.

Ein Schaltjahrfehler tritt auf, wenn Software diese Schaltjahrlogik nicht berücksichtigt oder fehlerhafte Logik verwendet. Dies kann sich auf Zuverlässigkeit, Verfügbarkeit oder sogar die Sicherheit des betroffenen Systems auswirken.

Sie müssen Schaltjahre berücksichtigen, wenn Sie arithmetische Vorgänge für eine Variable ausführen, die ein Datum darstellt. Es ist nicht sicher, davon auszugehen, dass ein Jahr 365 Tage lang ist. Ein Schaltjahr hat 366 Tage aufgrund des "Schalttags", der im Februar als 29. Tag hinzugefügt wurde.

Um ein Jahr korrekt vorauszuschreiten, bestimmen Sie, ob die Zeitspanne einen Schalttag enthält, und führen Sie dann die Berechnung mit der richtigen Anzahl von Tagen aus. Es ist besser, wenn das Jahr direkt fortgeschritten ist, mit einem entsprechenden Schalttag-Check am resultierenden Datum. Verwenden Sie alternativ eine etablierte Bibliotheksroutine, die Schaltjahre korrekt verarbeitet.

Codeanalysename: DATETIME_MANIPULATION_ASSUMING_365_DAYS_WITHOUT_LEAPYEAR_CHECK

Beispiel

Der folgende Code versucht, die aktuelle Systemzeit abzurufen, den Tag um ein Jahr zu erweitern, indem 365 Tage zum Feld "Tag" hinzugefügt und das Datum pro Schaltjahrregel angepasst wird. Das Ergebnis kann jedoch nicht auf denselben Monat/datum des nächsten Jahres fallen:

#include <Windows.h> 
 
void foo() 
{ 
    SYSTEMTIME st; 

    GetSystemTime(&st); 

    // Advance a year by adding 365 days 
    st.wDay += 365;    // C26864 
}

Um dieses Problem zu beheben, führen Sie das Feld "Jahr" direkt aus, und passen Sie das Datum pro Schaltjahrregel an:

#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; 
        } 
    } 
}

Heuristik

Diese Regel erkennt nur die Windows-Struktur SYSTEMTIME und die C-Struktur tm .

Diese Regel wird erzwungen, wenn das Datumsfeld von 365 Tagen direkt geändert wird. Es wird nicht berücksichtigt, ob der Wert des Datumsfelds einer anderen Variablen zugewiesen und dann bearbeitet wird und daher entsprechende Fehler fehlen kann.

Diese Regel ist eine Opt-In-Regel, d. h. die Codeanalyse sollte eine Regeldatei verwenden, und die Regel sollte explizit in die Regeldatei aufgenommen und aktiviert werden, damit sie angewendet werden kann. Weitere Informationen zum Erstellen eines benutzerdefinierten Regelsets für die Codeanalyse finden Sie unter Verwenden von Regelsätzen zum Angeben der C++ auszuführenden Regeln.

Siehe auch

C6393
C6394
C26861
C26862
C26863