C'nin Zaman Fonksiyonu "time" Üzerine Kısa Bir Yazı

Bu yazıda İngilizceden Türkçeye çevrilmemiş ya da çevrilememiş olan kelimeler çift tırnak içinde kullanılmıştır. Örnek koddaki (kullanılan yapının elemanlarının tek tek açıklanması gibi) her ayrıntı anlatılmamıştır. Okuyan kişilerin temel C programlama dili bilgisine sahip oldukları varsayılmıştır.

C ya da C++ ile kod yazarken ne zaman Standart C fonksiyonlarından “time” kullansam aynı şey geliyor aklıma : Tasarımı çok basit ama bir o kadar da kullanışlı! Neden böyle düşündüğümü kısaca açıklamaya çalışacağım.

Bilindiği üzere time fonksiyonunun klasik kullanımı aşağıdaki gibidir.
time_t t = time(NULL);

Bu şekilde “Epoch” olarak geçen 1 Ocak 1970 tarihi ve 00:00:00 saatinden, çağırmayı yaptığımız ana kadar geçen zamanı saniye olarak elde ederiz. Bu fonksiyonu ilk gördüğümde aklıma gelen ilk soru “Neden saniye?” şeklinde olmuştu. Aşağıda örnek kod ile durum ayrıntılandırılmıştır ancak burada kısa ve öz cevabı vermek gerekirse, geri dönüş değerinin saniye olması gerçekten büyük bir işlem kolaylığı sağlıyor!

Varsayalım ki yazdığınız kodda bir tarih bilgisi tutmanız ve bu tarih bilgisine de saniye, dakika, saat, gün, ay ve yıl ekleyip çıkartmanız gerekli. Genelde akla gelen ilk şeyler, tarih bilgisi nasıl tutulmalıdır, artık yıl hesabı, ekleme çıkarma gibi işlemlerde dikkat edilmesi gereken 28, 29, 30, 31 günlük aylar, gerektiği noktada yıl atlatmalar gibi bir çok istisnai duruma ilişkin sorulardır. Ama gerçekten bunlar üzerinde bu kadar düşünmeye gerek var mı?

Benim cevabım “Hayır!” şeklinde. Sebebi ise şu, istersem o an için geçerli tarih ve zaman bilgisi elde etmek amacıyla “time” fonksiyonu ile istersem de herhangi bir zaman için “mktime” fonksiyonu ile “Epoch” olarak geçen zamandan itibaren geçen süreyi saniye olarak alabilirim. Bundan sonra da ne kadar ötelemek veya geriye çekmek istiyorsam yaparım. Tabi tüm bu ekleme çıkarma işlemlerini saniye olarak yaparım ve gerekli yerlerde elimdeki saniye bilgisini “localtime” (veya “gmtime”) ile tarih ve zaman bilgisine çeviririm. Bu durumu ve daha fazlasını açıklayan örnek C kodu aşağıdaki gibidir.

Koda Dair Küçük Notlar:
Kodun yazımı için “man 2 time” ve “man ctime” şeklinde elde edilen kılavuz sayfalarından faydalanılmıştır.
TM_BASE _YEAR sabiti “struct tm” yapısındaki yıl değişkeninin 1900'den sonrası için ayarlanması sebebi ile doğru yılı elde etmek amaçlı olarak kullanılmaktadır.

TM_MONTH_SHIFT sabitinin kullanım amacı ise klasik olarak C'deki indekslemenin sıfırdan başlaması ile aynı durumdur : “struct tm” içindeki ay bölümünün indekslemesi sıfırdan başladığı için doğru ay gösterimi/hesabı yapabilmek için duruma göre bir eklemek ya da çıkarmak amacıyla kullanılmaktadır.



#include
#include
#include

#define TM_BASE_YEAR 1900
#define TM_MONTH_SHIFT 1

#define SECOND_PER_MINUTE 60
#define MINUTE_PER_HOUR 60
#define HOUR_PER_DAY 24



int main(int argc, char *argv[])
{
// Epoch'tan bu kodun çalıştığı ana kadar geçen süreyi saniye olarak al
time_t t = time(NULL);

// Elde ettiğin saniyeyi tarih ve zaman bilgisine çevir.
struct tm* pTm = localtime(&t);

// localtime ile elde edilen bilgiyi görüntüle
printf("%02d/%02d/%04d - %02d:%02d:%02d\n", pTm->tm_mday,
pTm->tm_mon + TM_MONTH_SHIFT,
pTm->tm_year + TM_BASE_YEAR,
pTm->tm_hour,
pTm->tm_min,
pTm->tm_sec
);


// İçinde bulunulan zamanı 15 gün ileriye al
t += (SECOND_PER_MINUTE * MINUTE_PER_HOUR * HOUR_PER_DAY) * 15;
// Elde ettiğin saniyeyi tarih ve zaman bilgisine çevir.
pTm = localtime(&t);
// localtime ile elde edilen bilgiyi görüntüle
printf("%02d/%02d/%04d - %02d:%02d:%02d\n", pTm->tm_mday,
pTm->tm_mon + TM_MONTH_SHIFT,
pTm->tm_year + TM_BASE_YEAR,
pTm->tm_hour,
pTm->tm_min,
pTm->tm_sec
);


// "29/11/2008 - 23:15:00" için uygun yapıyı hazırla
struct tm tms;
tms.tm_sec = 0;
tms.tm_min = 15;
tms.tm_hour = 23;
tms.tm_mday = 29;
tms.tm_mon = 11 - TM_MONTH_SHIFT;
tms.tm_year = 2008 - TM_BASE_YEAR ;
tms.tm_isdst = 0;

// Epoch'tan "29/11/2008 - 23:15:00" tarihine kadar geçen saniyeyi al
t = mktime(&tms);

// Elde ettiğin saniyeyi tarih ve zaman bilgisine çevir.
pTm = localtime(&t);
// localtime ile elde edilen bilgiyi görüntüle
printf("%02d/%02d/%04d - %02d:%02d:%02d\n", pTm->tm_mday,
pTm->tm_mon + TM_MONTH_SHIFT,
pTm->tm_year + TM_BASE_YEAR,
pTm->tm_hour,
pTm->tm_min,
pTm->tm_sec
);


// "28/02/2008 - 23:15:00" için uygun yapıyı hazırla
tms.tm_sec = 0;
tms.tm_min = 15;
tms.tm_hour = 23;
tms.tm_mday = 28;
tms.tm_mon = 2 - TM_MONTH_SHIFT;
tms.tm_year = 2008 - TM_BASE_YEAR ;
tms.tm_isdst = 0;

// Epoch'tan "28/02/2008 - 23:15:00" tarihine kadar geçen saniyeyi al
t = mktime(&tms);

// Elde edilen zamanı 1 gün ileriye al
t += (SECOND_PER_MINUTE * MINUTE_PER_HOUR * HOUR_PER_DAY) * 1;

// Elde ettiğin saniyeyi tarih ve zaman bilgisine çevir.
pTm = localtime(&t);


// localtime ile elde edilen bilgiyi görüntüle
printf("%02d/%02d/%04d - %02d:%02d:%02d\n", pTm->tm_mday,
pTm->tm_mon + TM_MONTH_SHIFT,
pTm->tm_year + TM_BASE_YEAR,
pTm->tm_hour,
pTm->tm_min,
pTm->tm_sec
);


// YANLIŞ bir tarih olan "29/02/2007 - 23:15:00" için uygun yapıyı hazırla
tms.tm_sec = 0;
tms.tm_min = 15;
tms.tm_hour = 23;
tms.tm_mday = 29;
tms.tm_mon = 2 - TM_MONTH_SHIFT;
tms.tm_year = 2007 - TM_BASE_YEAR ;
tms.tm_isdst = 0;

// Epoch'tan YANLIŞ bir tarih olan "29/02/2007 - 23:15:00" tarihine kadar geçen saniyeyi al
t = mktime(&tms);

// Elde ettiğin saniyeyi tarih ve zaman bilgisine çevir.
pTm = localtime(&t);
// localtime ile elde edilen bilgiyi görüntüle. Bakalım yanlış girilen için ne göreceğiz :)
printf("%02d/%02d/%04d - %02d:%02d:%02d\n", pTm->tm_mday,
pTm->tm_mon + TM_MONTH_SHIFT,
pTm->tm_year + TM_BASE_YEAR,
pTm->tm_hour,
pTm->tm_min,
pTm->tm_sec
);


return EXIT_SUCCESS;
}

Programın çıktısı aşağıdaki gibidir:
29/11/2008 - 23:46:12
14/12/2008 - 23:46:12
29/11/2008 - 23:15:00
29/02/2008 - 23:15:00
01/03/2007 - 23:15:00



« Önceki yazı - Sonraki yazı »
--------------------------

Yorumlar

Henüz yorum yazılmamış. İlk yorum yazan kişi olmak ister misiniz?

Yorum yaz

:

:
: