Uyarı C26864

Bir tarih-saat nesnesinin var gün alanı, düzgün artık yıl denetimi yapılmadan yılda 365 gün olduğu varsayılarak değiştirildi: expr

Bu kural Visual Studio 2022 17.8'e eklendi.

Açıklamalar

Gregoryen takvimde, tam olarak dört ile bölünebilen her yıl, tam olarak 100 ile bölünebilen yıllar dışında artık yıldır. 400 ile tam olarak bölünebiliyorlarsa centurial yıllar da artık yıllardır.

Yazılım bu artık yıl mantığını hesaba eklemediğinde veya hatalı mantık kullandığında artık yıl hatası oluşur. , güvenilirlik, kullanılabilirlik ve hatta etkilenen sistemin güvenliğini etkileyebilir.

Tarihi temsil eden bir değişken üzerinde aritmetik işlemler gerçekleştirirken artık yılları dikkate almanız gerekir. Bir yılın 365 gün olduğunu varsaymak güvenli değildir. Artık yıl, Şubat ayında 29. gün olarak eklenen 'artık gün' nedeniyle 366 güne sahiptir.

Bir yılı doğru şekilde ilerletmek için, zaman aralığının artık gün içerip içermediğini belirleyin, ardından hesaplamayı doğru gün sayısını kullanarak gerçekleştirin. Yılın doğrudan gelişmiş olması ve sonuçta elde edilen tarih üzerinde uygun bir artık gün denetimi olması daha iyidir. Alternatif olarak, artık yılları doğru işleyen yerleşik bir kitaplık yordamı kullanın.

Kod analizi adı: DATETIME_MANIPULATION_ASSUMING_365_DAYS_WITHOUT_LEAPYEAR_CHECK

Örnek

Aşağıdaki kod geçerli sistem saatini almaya, gün alanına 365 gün ekleyerek ve artık yıl başına tarihi ayarlayarak günü bir yıl ilerletmeye çalışır. Ancak, sonuç sonraki yılın aynı ayına/tarihine düşmeyebilir:

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

    GetSystemTime(&st); 

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

Bu sorunu çözmek için yıl alanını doğrudan ilerletip artık yıl kuralına göre tarihi ayarlayın:

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

Buluşsal yöntemler

Bu kural yalnızca Windows SYSTEMTIME yapısını ve C tm yapısını tanır.

Tarih alanı doğrudan 365 gün değiştirilirse bu kural uygulanır. Tarih alanının değerinin başka bir değişkene atanıp atanmadığını ve daha sonra işlenip işlenmediğini dikkate almaz ve bu nedenle eşdeğer hataları kaçırabilir.

Bu kural bir kabul kuralıdır, yani kod analizi bir kural kümesi dosyası kullanmalıdır ve kuralın kural kümesi dosyasına açıkça eklenmesi ve uygulanması için etkinleştirilmesi gerekir. Kod analizi için özel kural kümesi oluşturma hakkında daha fazla bilgi için bkz. Çalıştırılacak Kuralları Belirtmek C++ için Kural Kümelerini Kullanma.

Ayrıca bkz.

C6393
C6394
C26861
C26862
C26863