Avertissement C26864
Le champ Jour d’un objet
var
date-heure a été modifié en supposant que 365 jours par année sans vérification appropriée de l’année bissextile :expr
Cette règle a été ajoutée dans Visual Studio 2022 17.8.
Notes
Dans le calendrier grégorien, chaque année exactement divisible par quatre est une année bissextile, à l’exception des années qui sont exactement divisibles par 100. Les années centuriales sont aussi des années bissextiles si elles sont exactement divisibles par 400.
Un bogue de l’année bissextile se produit lorsque le logiciel ne tient pas compte de cette logique de l’année bissextile ou utilise une logique défectueuse. Cela peut affecter la fiabilité, la disponibilité ou même la sécurité du système concerné.
Vous devez prendre en compte les années bissextiles lorsque vous effectuez des opérations arithmétiques sur une variable qui représente une date. Il n’est pas sûr de supposer qu’une année est longue de 365 jours. Une année bissextile a 366 jours en raison du « jour bissextile » ajouté comme 29e jour en février.
Pour avancer correctement une année, déterminez si l’intervalle de temps contient un jour bissextile, puis effectuez le calcul à l’aide du nombre correct de jours. Il est préférable que l’année soit directement avancée, avec un contrôle de jour bissextile approprié à la date résultante. Vous pouvez également utiliser une routine de bibliothèque établie qui gère correctement les années bissextiles.
Nom de l’analyse du code : DATETIME_MANIPULATION_ASSUMING_365_DAYS_WITHOUT_LEAPYEAR_CHECK
Exemple
Le code suivant tente d’obtenir l’heure système actuelle, d’avancer le jour d’un an en ajoutant 365 jours au champ jour et en ajustant la date par règle d’année bissextile. Toutefois, le résultat peut ne pas tomber sur le même mois/date de l’année suivante :
#include <Windows.h>
void foo()
{
SYSTEMTIME st;
GetSystemTime(&st);
// Advance a year by adding 365 days
st.wDay += 365; // C26864
}
Pour résoudre ce problème, avancez le champ année directement et ajustez la date par règle d’année bissextile :
#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;
}
}
}
Heuristique
Cette règle reconnaît uniquement le struct Windows SYSTEMTIME
et le struct C tm
.
Cette règle est appliquée si le champ date est directement modifié par 365 jours. Elle ne prend pas en compte si la valeur du champ de date est affectée à une autre variable, puis manipulée, et peut donc manquer des erreurs équivalentes.
Cette règle est une règle d’opt-in, ce qui signifie que l’analyse du code doit utiliser un fichier d’ensemble de règles, et que la règle doit être explicitement incluse dans le fichier d’ensemble de règles et activée pour qu’elle soit appliquée. Pour plus d’informations sur la création d’un ensemble de règles personnalisé pour l’analyse du code, consultez Utiliser des ensembles de règles pour spécifier les C++
règles à exécuter.