Partilhar via


Aviso C26861

O campo de um objeto var de data e hora foi modificado 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.

Não é seguro adicionar ou subtrair algum número de ou para o campo ano, mês ou dia de um objeto de data e hora sem levar em conta os anos bissextos. Esse cálculo é comumente realizado para determinar a data de expiração de um certificado, por exemplo. Em muitas datas, um cálculo ingênuo pode produzir o resultado desejado. No entanto, quando o resultado é 29 de fevereiro (um dia bissexto) e o ano não é bissexto, o resultado é inválido.

Por exemplo, adicionar um ano a 2020-01-31 produz 2021-01-31. Mas adicionar um ano a 2020-02-29 produz 2021-02-29, que não é uma data válida porque 2021 não é um ano bissexto.

Tenha cuidado ao manipular variáveis que representam valores de data. Manipule anos bissextos e dias bissextos corretamente ou use uma API ou biblioteca que lide com aritmética de data com segurança.

Nome da análise de código: DATETIME_MANIPULATION_WITHOUT_LEAPYEAR_CHECK

Exemplo

O código a seguir avança a hora do sistema em um ano, incrementando o campo year do objeto date-time que representa a hora do sistema. No entanto, ele pode produzir um objeto de data e hora inválido se a data for 29 de fevereiro antes da modificação, porque o próximo ano não é um ano bissexto:

SYSTEMTIME st; 
GetSystemTime(&st); 
st.wYear++;  // warning C26861 

Para evitar a criação de um objeto de data-hora inválido devido a um ano bissexto, verifique se a data resultante ainda é válida e faça os ajustes necessários para torná-la válida, como neste exemplo:

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

Heurística

Atualmente, essa regra reconhece apenas o struct Windows SYSTEMTIME e o struct C tm .

Essa regra emprega uma heurística simplificada para encontrar alterações potencialmente arriscadas e relata avisos, a menos que haja uma verificação apropriada de ano bissexto ou dia bissexto. Ele não tenta verificar se a verificação de ano bissexto ou dia bissexto é executada corretamente para o objeto de data e hora modificado.

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
C26862
C26863
C26864