Artık yıl hesabı

"Eğer bir yılın son iki hanesi 4'e tam bölünüyorsa artık yıldır" diyorsanız yazının devamına bir göz atın...

İlköğretimden beri öğretilen bir bilgidir: "Eğer bir yılın son iki hanesi 4'e tam bölünüyorsa artık yıldır."

Evet doğru ama tam doğru değil. Mesela 1900 yılı artık yıl değildir.

Şu anda kullandığımız Gregoryen takvimine göre bir yılın artık yıl olması için:

  1. 4' tam bölünmesi
  2. 100'e tam bölünememesi,
  3. 400'e tam bölünmesi,
  4. 4000'e tam bölünememesi

gerekiyor. :)

Tekerleme gibi oldu ama işin aslı böyle.

Bir yılın artık yıl olup olmadığını tespit etmek için şu adımları gerçekleştirmek gerekir:

  1. Yıl, 4'e tam bölünüyorsa adım 2'ye geçin. Aksi durumda adım 5'e gidin.
  2. Yıl, 100'e tam bölünüyorsa adım 3'e gidin. Aksi durumda 4. adıma gidin.
  3. Yıl, 400'e tam bölünüyorsa adım 4'e gidin. Aksi durumda, adım 5'e gidin.
  4. Yıl artık yıldır. Adım 6 ya gidin.
  5. Yıl artık yıl değildir.
  6. :)

Bu adımları C# ta şu şekilde gerçekleştirebiliriz:

bool ArtikYilMi(int yil)
{
    return 
        yil % 4 == 0 && 
        (yil % 100 != 0 || yil % 400 == 0);
}

Bu şekilde 1900'den 2100 yılına (dikkat: 1900 ve 2100 dahil) kadar artık yıl olan yılları listeleyelim:

static bool ArtikYilMi(int yil)
{
    return
        yil % 4 == 0 &&
        (yil % 100 != 0 || yil % 400 == 0);
}

static void Main(string[] args)
{
    for (int i = 1900, sira = 1; i <= 2100; i++)
    {
        if (ArtikYilMi(i))
        {
            Console.Write(i + " ");
            if (sira++ % 7 == 0)
                Console.WriteLine();
        }
    }

    Console.ReadKey();
}

Çıktı:

Peki bu artık yıl hesabının bizler açısından önemi nedir?

Gayet basit, eğer programcılar artık yıl hesabını "son iki hane 4 e tam bölünüyorsa..." şeklinde yaparlarsa programlarında ciddi bir hata yapmış sayılırlar, özellikle muhasebe programları gibi işin içinde para işlerinin olduğu durumlarda :)

Ama merak etmeyin bizler, C# programcıları, böyle ufak tefek detaylarla ilgilenmiyoruz. :)

DateTime yapısı tüm bu sorunların üstesinden geliyor.

Aynı sorunu, DateTime yapısının (class değil dikkat!) static IsLeapYear metodu ile de çözebilirdik:

static bool ArtikYilMi(int yil)
{
    return
        yil % 4 == 0 &&
        (yil % 100 != 0 || yil % 400 == 0);
}

static void Main(string[] args)
{
    for (int i = 1900, sira = 1; i <= 2100; i++)
    {
        if (DateTime.IsLeapYear(i))
        {
            Console.Write(i + " ");
            if (sira++ % 7 == 0)
                Console.WriteLine();
        }
    }

    Console.ReadKey();
}

Program aynı çıktıyı verecektir.

İlerleyen zamanlarda DateTime yapısının pek bilinmeyen yönlerine değineceğim.

Herkese kolay gelsin.