Compartir vía


Advertencia C26864

El campo Día de un objeto var de fecha y hora se ha modificado suponiendo 365 días por año sin la comprobación de año bisiesto adecuada: expr

Esta regla se agregó en Visual Studio 2022 17.8.

Comentarios

En el calendario gregoriano, cada año exactamente divisible por cuatro es un año bisiesto, excepto por años que son exactamente divisibles en 100. Los siglos también son años bisiestos si son exactamente divisibles en 400.

Se produce un error de año bisiesto cuando el software no tiene en cuenta esta lógica de año bisiesto o usa lógica errónea. puede afectar a la confiabilidad, disponibilidad o incluso a la seguridad del sistema afectado.

Debe tener en cuenta años bisiestos al realizar operaciones aritméticas en una variable que represente una fecha. No es seguro suponer que un año es de 365 días. Un año bisiesto tiene 366 días debido al "día bisiesto" agregado como un día 29 en febrero.

Para avanzar correctamente un año, determine si el intervalo de tiempo contiene un día bisiesto y, a continuación, realice el cálculo con el número correcto de días. Es mejor si el año está directamente avanzado, con una comprobación de día bisiesto adecuada en la fecha resultante. Como alternativa, use una rutina de biblioteca establecida que controle los años bisiestos correctamente.

Nombre de análisis de código: DATETIME_MANIPULATION_ASSUMING_365_DAYS_WITHOUT_LEAPYEAR_CHECK

Ejemplo

El código siguiente intenta obtener la hora actual del sistema, avanzar el día por un año agregando 365 días al campo día y ajustando la regla de fecha por año bisiesto. Sin embargo, es posible que el resultado no se encuentre en la misma fecha o mes del próximo año:

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

    GetSystemTime(&st); 

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

Para corregir este problema, avance el campo de año directamente y ajuste la fecha por la regla del año bisiesto:

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

Heurística

Esta regla solo reconoce la estructura de Windows SYSTEMTIME y la estructura de C tm .

Esta regla se aplica si el campo de fecha se modifica directamente en 365 días. No tiene en cuenta si el valor del campo de fecha se asigna a otra variable y, a continuación, se manipula y, por tanto, puede perder errores equivalentes.

Esta regla es una regla de participación, lo que significa que el análisis de código debe usar un archivo de conjunto de reglas y la regla debe incluirse explícitamente en el archivo del conjunto de reglas y habilitarla para que se aplique. Para obtener más información sobre cómo crear un conjunto de reglas personalizado para el análisis de código, vea Usar conjuntos de reglas para especificar las C++ reglas que se van a ejecutar.

Consulte también

C6393
C6394
C26861
C26862
C26863