Tarih ve Saatin Yerel Zamana Dönüştürülmesi
Önceki Mutlak Zaman Sonraki
Tarih ve Saatin Yerel Zamana Dönüştürülmesi
ISO C standardı strftime işlevinin çıktısının, girdisi olan ikilik biçime dönüştürülmesi için herhangi bir işlev belirtmemiştir. Bu, ilk yıllarda farklı arayüzlerin az ya da çok başarılı çeşitli gerçeklemeler geliştirmeleri ile sonuçlanmıştır. Bunların ardından Unix standardı iki ek işlev tanımladı: strptime ve getdate. Her ikisi de tuhaf arayüzlere sahip olmasına karşın geniş kullanım alanı bulmuştur.
Düşük Seviyede Çözümleme
İlk işlev oldukça düşük seviyededir. Buna rağmen, iyi bilindiğinden yazılım geliştirirken sıklıkla kullnılır. Arayüzü ve gerçeklenmesi ağırlıkla, strptime çağrısı kurallarıyla tanımlanmış ve gerçeklenmiş olan getdate işlevinden etkilenmiştir.
char *strptime
(const char *dizge,
 const char *biçim,
 struct tm  *zaman)
işlev
strptime işlevi dizge dizgesini biçim dizgesine göre çözümleyerek sonucu zaman yapısına yazar.
Girdi dizgesi strftime işleviyle ya da başka bir yöntemle üretilmiş olabilir. Girdi dizgesinin içeriğinin insanlar açısından anlamlı olması gerekmez, biçim dizgesi ile eşleşebilen herhangi bir dizge olabilir (örn, "02:1999:9").
Kullanıcı ne yaptığını bilmelidir, yoksa girdi saçma sapan çözümlenebilir. Örneğin "1999112" dizgesi "%Y%m%d" biçimi kullanılarak 1999-1-12, 1999-11-2 ve hatta 19991-1-2 olarak çözümlenebilir. Kararlı sonuçlar almak için girdi dizgesine uygun ayraçların eklenmesi gerekir.
Biçim dizgesi, strftime işlevinin biçim dizgesinde kullanılan elemanlarla oluşturulur. Tek farkla; _, -, 0 ve ^ seçeneklerine izin verilmez. Girdide harf büyüklükleri gibi farklara bakılmadığından strftime işlevinin bazı belirli biçimleri bile strptime'da aynı işi yapar. İki işlev arasanıda bakışımın sağlanması için tüm biçimler desteklenmiştir.
E ve O değiştiricilerine strftime işlevinin kullanılmasına izin verdiği her yerde izin verilmiştir.
Biçimler şunlardır:
%a
%A
Yerele özgü kısaltılmış ya da tam gün ismi.
%b
%B
%h
Yerele özgü kısaltılmış ya da tam ay ismi.
%c
Yerele özgü tarih ve saat gösterimi.
%Ec
Yerele özgü diğer tarih ve saat biçimi olması dışında %c ile aynıdır.
%C
Yılın yüzyıllık parçası.
Bu biçim, biçim dizgesi ayrıca bir %y biçimi içeriyorsa anlamlı olarak çözümlenir.
%EC
Yerele özgü dönem gösterimi.
%C'den farklı olarak, bazı kültürlerde yıllar, Gregoryen yıllarına göreli bir yılı başlangıç yılı alarak gösterilebilmektedir.
%d
%e
1 ile 31 arasında bir değer olarak ayın gün numarası (tek rakamlı sayıların önüne 0 konulsa da olur konulmasa da).
%Od
%Oe
Yerele özgü diğer sayısal sembollerin kullanılması dışında %d ile aynıdır.
Tek rakamlı sayıların önüne 0 konulsa da olur konulmasa da.
%D
%m/%d/%y biçimine eşdeğerdir.
%F
ISO 8601 tarih biçimi olan %Y-%m-%d ile eşdeğerdir.
strftime'da ISO C99 oluşumu olan bir GNU oluşumudur.
%g
00 ile 99 arasında yılın yüzyıllık parçası olmaksızın ISO hafta numarasına bağlı yıl numarasıdır.
Not
Şimdilik tam olarak gerçeklenmemiştir. Biçim olarak tanınır ama tm yapısında ilgili alana birşey yazılmaz.
strftime'da da GNU oluşumu olan bir GNU oluşumudur.
%G
ISO hafta numarasına göre yıl.
Not
Şimdilik tam olarak gerçeklenmemiştir. Biçim olarak tanınır ama tm yapısında ilgili alana birşey yazılmaz.
strftime'da da GNU oluşumu olan bir GNU oluşumudur.
%H
%k
00 ile 23 arasında bir sayısal değer olarak 24 saatlik saat gösterimi.
%k, strftime'da da GNU oluşumu olan bir GNU oluşumudur.
%OH
Yerele özgü diğer sayısal sembollerin kullanılması dışında %H ile aynıdır.
%I
%l
01 ile 12 arasında bir sayısal değer olarak 12 saatlik saat gösterimi.
%l, strftime'da da GNU oluşumu olan bir GNU oluşumudur.
%OI
Yerele özgü diğer sayısal sembollerin kullanılması dışında %I ile aynıdır.
%j
1 ile 366 arasında yılın gün numarası.
Başa 0 konulsa da olur konulmasa da.
%m
1'den 12'ye kadar ay numarası.
Başa 0 konulsa da olur konulmasa da.
%Om
Yerele özgü diğer sayısal sembollerin kullanılması dışında %m ile aynıdır.
%M
0'dan 59'a kadar dakika.
Başa 0 konulsa da olur konulmasa da.
%OM
Yerele özgü diğer sayısal sembollerin kullanılması dışında %M ile aynıdır.
%n
%t
Boşluklarla eşleşirler.
%p
%P
Yerele özgü AM veya PM dizgesi.
Bu biçim, %I veya %l ayrıca kullanılmamışsa kullanışsızdır. Bu değerlerin atanmamış olduğu yerellerde başka sorunlara da yol açar ve bu nedenle dönüşüm başarısız olur.
%P strftime'da da GNU oluşumu olan bir GNU oluşumudur..
%r
The complete time using the AM/PM format of the current locale.
A complication is that the locale might not define this format at all and therefore the conversion fails.
%R
The hour and minute in decimal numbers using the format %H:%M.
%R, strftime'da da GNU oluşumu olan bir GNU oluşumudur.
%s
Mutlak zaman başlangıcından (epoch) yani 1970-01-01 00:00:00 UTC'den beri geçen saniye sayısı. Artık saniye desteği yoksa artık saniyeler hesaba katılmaz.
%s, strftime'da da GNU oluşumu olan bir GNU oluşumudur..
%S
0'dan 60'a kadar saniye.
Başa 0 konulsa da olur konulmasa da.
Not
Unix belirtimi iki artık saniyenin gösterilmesinin de mümkün olması varsayımıyla bu değerin üst sınırının 61 olduğunu söyler. Bu değeri 61 olarak hiç görmeyeceksiniz, çünkü 1 artık saniyeden fazlasına sahip bir dakika yoktur ama efsane sürüyor.
%OS
Yerele özgü diğer sayısal sembollerin kullanılması dışında %S ile aynıdır.
%T
%H:%M:%S biçimine eşdeğer olarak yorumlanır.
%u
1'den 7'ye kadar gün isminin numarası. Pazartesi, haftanın birinci günüdür.
Başa 0 konulsa da olur konulmasa da.
Not
Şimdilik tam olarak gerçeklenmemiştir. Biçim olarak tanınır ama tm yapısında ilgili alana birşey yazılmaz.
%U
0'dan 53'e kadar hafta numarası.
Başa 0 konulsa da olur konulmasa da.
%OU
Yerele özgü diğer sayısal sembollerin kullanılması dışında %U ile aynıdır.
%V
1'den 53'e kadar ISO 8601:1988 hafta numarası.
Başa 0 konulsa da olur konulmasa da.
Not
Şimdilik tam olarak gerçeklenmemiştir. Biçim olarak tanınır ama tm yapısında ilgili alana birşey yazılmaz.
%w
0'dan 6'ya kadar gün isminin numarası. Pazar, haftanın ilk günüdür.
Başa 0 konulsa da olur konulmasa da.
Not
Şimdilik tam olarak gerçeklenmemiştir. Biçim olarak tanınır ama tm yapısında ilgili alana birşey yazılmaz.
%Ow
Yerele özgü diğer sayısal sembollerin kullanılması dışında %w ile aynıdır.
%W
0'dan 53'e kadar hafta numarası.
Başa 0 konulsa da olur konulmasa da.
Not
Şimdilik tam olarak gerçeklenmemiştir. Biçim olarak tanınır ama tm yapısında ilgili alana birşey yazılmaz.
%x
Yerele özgü kısa tarih gösterimi.
%Ex
Yerele özgü diğer veri gösterimlerinin kullanılması dışında %x gibidir.
%X
Yerele özgü saat gösterimi.
%EX
Yerele özgü diğer saat gösterimlerinin kullanılması dışında %x gibidir.
%y
0 ile 99 arasında yılın yüzyıllık parçası olmaksızın yıl numarası.
Başa 0 konulsa da olur konulmasa da.
%C olmaksızın bu biçim nasıl kullanılacak diye bir soru sorabilirsiniz. strptime işlevi 69'dan 99'a kadar değerleri 1969'dan 1999'a kadar, 0'dan 68'e kadar değerleri de 2000'den 2068'e kadar yıllara karşılık olarak ele alacaktır. Fakat bazı veri girdilerinde bu ampirik yaklaşım başarısız olabilir.
Bu nedenle %y biçiminden uzak durup yerine %Y kullanmak en iyisidir.
%Ey
Yerelin diğer gösteriminde %EC'den itibaren geçen yıl sayısı.
%Oy
Yerelin diğer gösteriminde %C başlangıcından itibaren geçen yıl sayısı.
%Y
Gregoryen takvimine göre tam yıl.
%EY
Diğer tam yıl gösterimi.
%z
RFC 822/ISO 8601:1988 tarzı zaman dilimi.
%Z
Zaman dilimi kısaltması.
Not
Şimdilik tam olarak gerçeklenmemiştir. Biçim olarak tanınır ama tm yapısında ilgili alana birşey yazılmaz.
%%
Tek bir % karakteri.
Biçim dizgesindeki diğer karakterler girdi dizgesindekilerle eşleşmelidir. Ancak girdi dizgesindeki boşluklar biçim dizgesinde bulunmayabileceği gibi daha fazla sayıda da bulunabilir.
Taşınabilirlik Bilgisi
XPG standardı, iki dönüşüm belirtimi arasında en azından bir boşluk (isspace ile belirtilenler) ya da bir alfanumerik olmayan karakter konulmasını tavsiye eder. GNU C kütüphanesi böyle bir sınırlama yapmaz ama diğer kütüphaneler "%d%m%Y%H%M%S" gibi bir biçim dizgesini yanlış çözümleyebilir.
strptime işlevi dizgeleri sağdan sola doğru işleme tabi tutar. Her olası girdi elemanı (boşluklar, kendisi olan karakterler, biçimler) için sırayla bakılır. Eğer girdiyle biçim eşleştirilemezse işlev işlemi durdurur. Girdi ve biçim dizgelerinin kalanı işleme tabi turulmaz.
İşlev, işlenmeyen ilk karaktere bir gösterici ile döner. Eğer girdi dizgesi, biçim dizgesinde gerekli karakterlerden fazla karakter içeriyorsa, dönüş değeri son işlenen girdi karakterinden hemen sonraki karakteri gösterir. Eğer girdi dizgesi tamamen tüketilmişse dönüş değeri dizgenin sonundaki boş karakteri gösterir. Bir hata oluşmuşsa, yani işlev biçim dizgesini tam eşleştirememişse, işlev NULL ile döner.
İşlevin XPG standardındaki belirtimi, bilginin bir kaç önemli parçasını dışarda bıraktığından oldukça muğlaktır. En önemlisi, doğrudan doğruya farklı biçimlerle ilklendirilmemiş tm elemanlarının ne olacağı belirlenmemiştir. Farklı Unix sistemlerindeki gerçeklemeler bu bakımdan değişiklikler gösterir.
GNU libc gerçeklemesi doğrudan ilklendirilmemiş alanlara dokunmaz. tm_wday ve tm_yday alanları bunun dışındadır. Yıl, ay veya tarih elemanları değişmişse bu alanların değerleri yeniden hesaplanır. Bunun iki faydası vardır:
  • strptime işlevini yeni bir girdi dizgesi ile çağırmadan önce, işleve aktaracağınız tm yapısını hazılamalısınız. Bu normalde yapının tüm elemanlarının sıfır olacağı anlamına gelir. Bunun yerine tüm alanlara INT_MAX değerini de atayabilirsiniz. Böylece işlev çağrısının hangi elemanlara değer atadığını saptayabilirsiniz. Bunu sıfırlarla yapamazdınız, çünkü atanan bazı değerler zaten sıfır olacaktır.
    tm yapısının ilgilendiğiniz alanlarına işlev çağrısı sırasında bir değer atanıp atanmadığını saptamak isterseniz yapıyı dikkatli ilklendirmelisiniz.
  • struct tm değerini peşpeşe yapacağınız strptime çağrıları ile oluşturabilirsiniz. Bir dizgede tarih başka bir dizgede de saat gösterimi bulunan iki dizgeyi ayrı ayrı çözümleten bir uyulama için bu yararlıdır. Bir dizgeyi çözümledikten sonra yapıyı temizlemden yapacağınız ikinci çözümleme ile tam yerel zamanı elde edebilirsiniz.
Aşağıdaki örnekte ya US tarzında ya da ISO 8601 biçiminde olabilen bir tarih bilgisi içeren bir dizgeyi çözümleyen bir işlev gösterilmiştir:
const char *
parse_date (const char *input, struct tm *tm)
{
  const char *cp;

  /* Önce yapıyı temizleyelim.  */
  memset (tm, '\0', sizeof (*tm));

  /* İlk olarak ISO biçimine bakalım.  */
  cp = strptime (input, "%F", tm);
  if (cp == NULL)
    {
      /* Eşleşme yok, o halde US biçimini deneyelim.  */
      cp = strptime (input, "%D", tm);
    }

  return cp;
}
Genel Zaman Gösterimi Çözümlemesi
Unix standardı tarih dizgelerini çözümlemek için başka bir işlev tanımlar. Arayüz tuhaftır ama uygulamanıza uygun düşecek olursa işlev en iyisidir. Bir durağan ayrılmış değişkene gösterici ile döndüğünden ve bir genel değişkenle genel bir durum (bir ortam değişkeni) kullandığından çok evreli uygulama ve kütüphanelerde sorun çıkarır.
getdate_err
değişken
Son başarısız getdate çağrısının hata kodunu içeren int türünde bir değişkendir. Tanımlı değerleri şunlardır:
1
DATEMSK ortam değişkeni tanımsız ya da boş.
2
DATEMSK ortam değişkeni ile belirtilen şablon dosyası açılamadı.
3
Şablon dosyası ile ilgili bilgiler alınamadı.
4
Şablon dosyası normal bir dosya değil.
5
Şablon dosyası okunurken bir G/Ç hatası oluştu.
6
İşlevin çalışması için bellek yetersiz.
7
Şablon dosyası eşleşen bir şablon içermiyor.
8
Girdi olarak verilen tarih geçersiz. Bu tarihler Şubat'ın 31'ini içeren ya da time_t türünde bir değişkenle ifade edilemeyen tarihler olabilir.
struct tm *getdate
(const char *dizge)
işlev
getdate arayüzü bir dizgeyi çözümleyip bir değer döndürecek bir işlev için olası en basit arayüzdür. dizge bir girdi dizgesidir ve sonuç bir dutağan olarak ayrılmış değişkende döndürülür.
Dizgenin nasıl işleme sokulduğu ile ilgili ayrıntılar kullanıcıdan gizlenmiştir. Aslında, yazılımın da denetiminin dışında olabilir. Karşılaştırma yapılacak biçim dizgeleri DATEMSK ortam değişkeni ile belirtilen bir dosyadadır. Bu dosya strptime işlevine aktarılabilecek biçim dizgelerinden oluşmuş satırlar içerir.
getdate işlevi bu biçim dizgelerini sırayla okuyarak girdi dizgesi ile eşleştirmeye çalışır. Girdi dizgesi ile tamamen eşleşen ilk satır kullanılır.
Biçim dizgesi ile ilklendirilmemiş elemanlar tekrar bir getdate çağrısı yapılana kadar öylece kalır.
getdate tarafından tanınan biçimler strptime iişlevininkilerle aynıdır. Bunlar için önceki bölümdeki açıklamalara bakabilirsiniz. strptime davranışına ek olarak bir kaç ek davranış vardır:
  • Eğer %Z biçimi yerel zamanda verilmişse, çalışma anı ortamının o anki zaman diliminin zamanına değil, zaman diliminin eşleştiği o anki zamana tabanlanır.
    Not
    Bu şimdilik gerçeklenmemiştir. Sorun, zaman dilimi isimlerinin eşsiz olmamasıdır. ABD ile diğer ülkeler için aynı olarak kabul edilen bir sabit zaman dilimi (örn, EST ABD Doğu Sahili Zamanı anlamında) verildiğinde ABD dışındaki ülkeler açısından işlev başarısız olacaktır. Şimdiye kadar buna iyi bir çözüm bulamadık.
  • Eğer sadece haftanın günü belirtilmişse, seçilen gün o anki tarihe bağlı olacatır. Eğer o anki haftanın günü tm_wday değerine eşit ya da ondan büyükse o anki haftanın günü, aksi takdirde sonraki haftanın günü seçilir.
  • Benzer bir ampirik yöntem de sadece ayın verildiği yılın belirtilmediği durumla ilgilidir. Eğer ay, o anki aya eşit ya da büyükse, o anki yıl, aksi takdirde bir sonraki yıl kullanılır. Açıkça belirtilmemişse ayın ilk günü verilmiş varsayılır.
  • Biçimde açıça belirtilmemişse o anki saat, dakika ve saniye değeri kullanılır.
  • Bir tarih belirtilmemişse ve zaman, o anki zamandan daha küçükse ertesi günün tarihi aksi takdirde o günkü tarih alınır.
Şablon dosyasındaki biçimin sadece biçim elemanlarını içermediği unutulmamalıdır. Aşağıda olası biçim dizgelerinin bir listei verilmiştir (Unix standardından alınmıştır):
%m
%A %B %d, %Y %H:%M:%S
%A
%B
%m/%d/%y %I %p
%d,%m,%Y %H:%M
at %A the %dst of %B in %Y
run job at %I %p,%B %dnd
%A den %d. %B %Y %H.%M Uhr
Gördüğünüz gibi, şablon listesi run job at %I %p,%B %dnd gibi çok özel dizgeler içerebilir. Bu listedeki şablonları kullanarak ve o anki zamanın Mon Sep 22 12:19:47 EDT 1986 olduğunu kabul ederek verilen girdiler için şu sonuçları aldık:
Girdi Eşleşen Sonuç
Mon %a Mon Sep 22 12:19:47 EDT 1986
Sun %a Sun Sep 28 12:19:47 EDT 1986
Fri %a Fri Sep 26 12:19:47 EDT 1986
September %B Mon Sep 1 12:19:47 EDT 1986
January %B Thu Jan 1 12:19:47 EST 1987
December %B Mon Dec 1 12:19:47 EST 1986
Sep Mon %b %a Mon Sep 1 12:19:47 EDT 1986
Jan Fri %b %a Fri Jan 2 12:19:47 EST 1987
Dec Mon %b %a Mon Dec 1 12:19:47 EST 1986
Jan Wed 1989 %b %a %Y Wed Jan 4 12:19:47 EST 1989
Fri 9 %a %H Fri Sep 26 09:00:00 EDT 1986
Feb 10:30 %b %H:%S Sun Feb 1 10:00:30 EST 1987
10:30 %H:%M Tue Sep 23 10:30:00 EDT 1986
13:30 %H:%M Mon Sep 22 13:30:00 EDT 1986
İşlevin dönüş değeri struct tm türündeki bir durağan ayrılmış değişkene göstericidir, bir hata oluşmuşsa boş gösterici döner. Sonuç sadece sonraki getdate çağrısına kadar geçerlidir. Bu, işlevi çok evreli uygulamalar açısından kullanışsız yapar.
errno değişkeni değiştirilmez. Hta değerleri getdate_err genel değişkeninde saklanır. Olası hata değerleri ve açıklamaları için yukarıya bakınız.
Uyarı
getdate işlevi hiçbir zaman SUID'li yazılımlarda kullanılmamalıdır. Sebep belli: işlev DATEMSK ortam değişkeninde belirtilen bir dosyayı kullanıyor; dosyada bazı bozuk girdiler (ikilik veri gibi) varsa yazılım çökecektir.
int getdate_r
(const char *dizge,
 struct tm  *zaman)
işlev
getdate_r işlevi getdate işlevinin evresel sürümüdür. getdate_err genel değişkenini kullanmaz, hata kodunu işlevin kendisi döndürür. Hata oluşmamışsa işlev sıfır döndürür. İşlevin döndürdüğü hata kodları getdate_err değişkeninin açıklamasındaki hata kodları ile aynıdır.
Bundan başka, getdate_r işlevi yerel zamanı bir durağan değişkende değil, struct tm türünde bir değişken olan ikinci argümanda saklar.
Bu işlev Unix standardında tanımlanmamıştır. Buna rağmen birçok Unix sisteminde kullanılmaktadır.
getdate işlevi için belirtilen SUID'li yazılımlarla ilgili uyarı bu işlev için de geçerlidir.
Önceki Üst Ana Başlık Sonraki
Zaman Değerlerinin Biçimlenmesi Başlangıç Zaman Diliminin TZ ile Belirtilmesi
Bir Linux Kitaplığı Sayfası