Partilhar via


Aviso C26864

O campo Dia de um objeto var de data e hora foi modificado assumindo 365 dias por ano sem a verificação adequada do ano bissexto: expr

A regra foi adicionada no Visual Studio 2022 17.8.

Comentários

No calendário gregoriano, todo ano exatamente divisível por quatro é um ano bissexto - exceto para anos que são exatamente divisíveis por 100. Os anos centuriais também são anos bissextos se forem exatamente divisíveis por 400.

Um bug do ano bissexto ocorre quando o software não leva em conta essa lógica do ano bissexto ou usa uma lógica falha. Isso pode afetar a confiabilidade, a disponibilidade ou até mesmo a segurança do sistema afetado.

Você deve levar em conta os anos bissextos ao executar operações aritméticas em uma variável que representa uma data. Não é seguro presumir que um ano tem 365 dias de duração. Um ano bissexto tem 366 dias por causa do 'dia bissexto' adicionado como 29º dia em fevereiro.

Para avançar corretamente um ano, determine se o intervalo de tempo contém um dia bissexto e, em seguida, execute o cálculo usando o número correto de dias. É melhor se o ano for diretamente avançado, com uma verificação apropriada do dia bissexto na data resultante. Como alternativa, use uma rotina de biblioteca estabelecida que lide com anos bissextos corretamente.

Nome da análise de código: DATETIME_MANIPULATION_ASSUMING_365_DAYS_WITHOUT_LEAPYEAR_CHECK

Exemplo

O código a seguir tenta obter a hora atual do sistema, avançar o dia em um ano adicionando 365 dias ao campo de dia e ajustando a regra de data por ano bissexto. No entanto, o resultado não pode cair no mesmo mês/data do ano seguinte:

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

    GetSystemTime(&st); 

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

Para corrigir esse problema, avance o campo do ano diretamente e ajuste a data de acordo com a regra do ano bissexto:

#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

Essa regra reconhece apenas o struct Windows SYSTEMTIME e o struct C tm .

Essa regra será aplicada se o campo de data for modificado diretamente por 365 dias. Ele não considera se o valor do campo de data é atribuído a outra variável e, em seguida, manipulado e, portanto, pode perder erros equivalentes.

Essa regra é uma regra de aceitação, o que significa que a análise de código deve usar um arquivo de conjunto de regras, e a regra deve ser explicitamente incluída no arquivo de conjunto de regras e habilitada para que ela seja aplicada. Para obter mais informações sobre como criar um conjunto de regras personalizado para análise de código, consulte Usar conjuntos de regras para especificar as C++ regras a serem executadas.

Confira também

C6393
C6394
C26861
C26862
C26863