Warnung C26861
Das Feld eines Datum-Uhrzeit-Objekts
var
wurde ohne ordnungsgemäße Schaltjahrüberprüfung geändert: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.
Es ist nicht sicher, einige Zahlen zu oder aus dem Jahr-, Monats- oder Tagesfeld eines Datum-Uhrzeit-Objekts zu addieren oder zu subtrahieren, ohne Schaltjahre zu berücksichtigen. Diese Berechnung wird häufig durchgeführt, um beispielsweise das Ablaufdatum für ein Zertifikat zu bestimmen. Auf vielen Datumsangaben kann eine naive Berechnung das gewünschte Ergebnis erzeugen. Wenn das Ergebnis jedoch der 29. Februar (ein Schalttag) und das Jahr kein Schaltjahr ist, ist das Ergebnis ungültig.
Beispielsweise erzeugt das Hinzufügen eines Jahres zu 2020-01-31 2021-01-31. Das Hinzufügen eines Jahres zu 2020-02-29 erzeugt jedoch 2021-02-29, was kein gültiges Datum ist, da 2021 kein Schaltjahr ist.
Seien Sie vorsichtig, wenn Sie Variablen bearbeiten, die Datumswerte darstellen. Behandeln Sie Schaltjahre und Schalttage ordnungsgemäß, oder verwenden Sie eine API oder Bibliothek, die Datumsarithmetik sicher verarbeitet.
Codeanalysename: DATETIME_MANIPULATION_WITHOUT_LEAPYEAR_CHECK
Beispiel
Mit dem folgenden Code wird die Systemzeit um ein Jahr erhöht, indem das Jahrfeld des Datum-Uhrzeit-Objekts erhöht wird, das die Systemzeit darstellt. Es kann jedoch ein ungültiges Datum-Uhrzeit-Objekt erzeugen, wenn das Datum vor der Änderung 29. Februar war, da das nächste Jahr kein Schaltjahr ist:
SYSTEMTIME st;
GetSystemTime(&st);
st.wYear++; // warning C26861
Um das Erstellen eines ungültigen Datums-Uhrzeit-Objekts aufgrund eines Schaltjahrs zu vermeiden, überprüfen Sie, ob das resultierende Datum noch gültig ist, und nehmen Sie die erforderlichen Anpassungen vor, um es gültig zu machen, wie im folgenden Beispiel gezeigt:
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;
}
}
Heuristik
Derzeit erkennt diese Regel nur die Windows-Struktur SYSTEMTIME
und die C-Struktur tm
.
Diese Regel verwendet eine vereinfachte Heuristik, um potenziell riskante Änderungen zu finden, und meldet Warnungen, es sei denn, es gibt ein geeignetes Schaltjahr oder eine Schalttagüberprüfung. Es wird nicht versucht, zu überprüfen, ob die Schaltjahr- oder Schalttagüberprüfung für das geänderte Datum-Uhrzeit-Objekt ordnungsgemäß ausgeführt wird.
Diese Regel ist eine Opt-In-Regel, was bedeutet, dass die Codeanalyse eine Regelsatzdatei verwenden sollte, und die Regel sollte explizit in die Regelsatzdatei 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.