2 Ocak 2016 Cumartesi

C'de Time API'leri

C Dili
C dilinde zaman (time) ile çalışmak maharet istiyor.
Aşağıda buradan aldığım C dilinde kullanılabilecek çağrıların birbiri ile olan ilişkisini gösteren güzel bir şekil var. Bu yazıda şekildeki metodları ve eksik kalan kısımlar için POSIX tarafından sağlanan yetenekleri incelemeye çalıştım.


Veri Yapıları
time_t 
std::time_t yazısına taşıdım.

struct time - broken time olarak ta bilinir
struct tm yazısına taşıdım.

time

time metodu hem Posix hem de Windows sistemlerde 1 Ocak 1970 (UTC) gece yarısından (00:00:00) beri geçen süreyi saniye çözünürlüğünde alabilmemizi sağlar. (C dili biraz eski olduğu için çözünürlük saniye seviyesinde kalmış, daha yeni dillerde çözünürlük saniyeden yüksek olabiliyor) Bu API tarafindan döndürülen time_t veri tipi C standardı tarafından sabitlenmemiştir ve bazı platformlarda 32 bit bazılarındaysa 64 bit olabilmektedir. Eğer metodu çağrısında hata varsa -1 döner

The time function returns the implementation’s best approximation to the current calendar time. The value (time_t)(-1) is returned if the calendar time is not available.
time() ile ilgili notlar
Gnu C kütüphanesi Unix için derlenirse time API'si gettimeofday metodunu çağırarak tv.sec alanının değerini döndürür.
Linux içinse bir kernel çağrısı yaparak ve aldığı değeri döndürür.

ctime ve asctime (sabit formatta string'e çevirme)
ctime ve asctime ürettikleri string'in sonuna yeni satır (eol) karakteri eklerler. Bu metodlar yerine strftime kullanılması daha iyi olur.

ctime
verilen time_t saniyesini yerel saat diliminde string'e çevirir. Bu metod yerine, varsa ctime_r kullanılmalı.

asctime
asctime() metodu yazısına taşıdım.

strftime - struct tm yapısını formatlı string'e çevirir
Bu metodu kullanabilmek için şu satır dahil edilir.
#include <time.h>
Kullanılabilecek çevirme seçenekleri burada. Her seçenek portable değil. Portable olmak için kullanılabilecek seçenekler şunlar


If you want your code to be portable, your format ("fmt")
argument should use only the conversion specifiers defined by
the ANSI C standard (C89, to play safe).  These are
"aAbBcdHIjmMpSUwWxXyYZ%".
Seçeneklerde küçük harfler kısaltılmış isimleri, büyükler ise uzun hallerini göstermek için kulllanılmış.
Aşağıda bazılarını açıklamaları var.

Çok kullanılan seçenekler şöyle%b : Kısaltılmış ay ismi (Jun vs. g.b.)
%c : Seçili locale'e göre formatlama yapar. Çok kullanışlıdır.

%d : gün 
%m : ay
%Y : Yıl

%H : 24 saat cinsinden saat
%M : Dakika
%S: Saniye

Örneği buradan aldım.
char buff[20];
struct tm * timeinfo = localtime (&mtime);
strftime(buff, sizeof(buff), "%b %d %H:%M", timeinfo);
Şöyle kullanırız.
struct tm ts = ...;

char buffer[1024];

char format[512] = "%Y%m%d-%H%M%S";
strftime(buffer, sizeof(buffer), format, &ts); 
Çıktı olarak şunu alırız.
20151229-212305

strftime alternatifi
std::put_time kullanılabilir. Örnek:
#include <iostream>
#include <iomanip>
#include <ctime>

int main()
{
    auto t = std::time(nullptr);
    auto tm = *std::localtime(&t);
    std::cout << std::put_time(&tm, "%d-%m-%Y %H-%M-%S") << std::endl;
}

strptime -  formatlı string'i struct tm yapısına çevirir
strptime yazısına taşıdım.

gmtime ve localtime - saniyeden broken-down time'e çevirme

locattime
localtime ve gmtime yazısına taşıdım.

gmtime
localtime ve gmtime yazısına taşıdım.

mktime ve timegm ile ilgili notlar - broken-down time'dan saniyeye çevirme
mktime
std::mktime metodu yazısına taşıdım.

timegm
Bazı platformlarda - örneğin Linux gibi - timegm() tanımlı. Bu metod broken-down formattaki UTC saati  tekrar time_t veriyapısına döndürür. Eğer timegm metodu çalışılan platformda yoksa aşağıdaki gibi bir çözüm üretilebilir.

Bu metod içinde tzset() çağırılınca <time.h> içinde extern long timezone olarak tanımlanan değeri de atıyor. Bu değer bulunduğumuz saat dilimine göre UTC ile aramızdaki saniye farkını tutuyor. mktime metodu içinde saniye hesaplanırken timezone değeri de hesaba katılıyor(Satır 117)

Hiç yorum yok:

Yorum Gönder