Saat kaç?

Merhaba,
Bildiğiniz gibi bu yıl, Türkiye'de Yaz Saati geçişi Mart ayının son Pazar sabahından, Mart ayının son Pazartesi sabahına alındı. Normal şartlar altında Windows işletim sistemleri, eğer otomatik geçişe ayarlandılarsa, 27 Mart Pazar sistem saatini sabah 3:00'te bir saat ileri alacaklar. Dolayısıyla 24 saat boyunca sistem saatleri 1 saat ileride olacaktır. Bu durum kimi kullanıcılar için pek de önemli değilse de kimi kurumlarda oldukça önem kazanmaktadır. Microsoft, Mart ayının 4. Haftasının sonlarına doğru bir yama yayınlayacak. Konuyla ilgili olarak Yaz saati uygulaması çözümü sayfasında tüm detayları bulabilirsiniz. Bu yama, sisteme "Turkey Standard Time" adlı yeni bir zaman dilimi ekleyecek. Ancak, sistem otomatik olarak bu zaman dilimine atanmayacak. Sistemin zaman dilimi ayarlarını elle yapmak mümkün olduğu gibi bir takım araçlarla yaptırmak da mümkün. Tam da bu nokta yazımızın konusu. Öyle bir uygulama geliştirelim ki hem Windows XP/ 2003 Server, hem de Windows Vista/ 2008 Server ve de Windows 7/Windows Server 2008 R2 işletim sistemleri üzerinde çalışsın. Bu uygulama herhangi bir çalışma zamanına (Runtime) ihtiyaç duymasın. Öte yandan istenen TimeZone'a (Zaman Dilimine) sistemi geçirsin. Ve hatta mümkünse eğer zaman dilimindeki Yaz Saati geçiş tarihini Mart ayının son Pazartesi gününe alsın ve de istendiğinde tekrar Yaz Saati geçişini Mart ayının son Pazar gününe geri getirsin.
İhtiyaçları göz önünde bulundurduğumuzda geliştirme dilini VC++ olarak kararlaştırabiliriz. .NET ortamı daha kolay olabilirdi ancak tüm sistemlerde .NET kurulu olmayabilir. Aynı şekilde PowerShell için de geliştirilmiş çözümler mevcut ancak yine her sistemde PowerShell kurulu olmayabilir. Oysa tüm sistemlerde VC Runtime Library'si (Çalışma Zamanı Kütüphanesi) mutlaka vardır. Tabii bu noktada static linking'i (Multi-threaded (/MT) ) kullanmalıyız ki herhangi bir çalışma zamanına bağlı kalmayalım.

Pekiyi nereden başlayacağız ?

Windows Fonksiyonlarından SetDynamicTimeZoneInformation ve SetTimeZoneInformation fonksiyonlarını kullanmamız gerekecek. Dinamik olan fonksiyon grubu Windows Vista ile birlikte ortaya çıktı. Daha eski işletim sistemlerinde bu fonksiyon çalıştırılamayacak. Bu durumda önümüzde iki yöntem var :
#1 İşletim Sisteminin versiyon bilgisini kontrol etmek
#2 Bu fonksiyonlar kernel32.dll modülünden export edildikleri için LoadLibrary ile bu modülü yüklemek ve sonra bu modül içinde SetDynamicTimeZoneInformation fonksiyonunu aramak. Eğer bulunamazsa o zaman eski fonksiyonu, yani SetTimeZoneInformation fonksiyonunu çağırmak.

Ben uygulamada ikinci yöntemi tercih ettim. SetDynamicTimeZoneInformation ve SetTimeZoneInformation fonksiyonlarını kullanabilmek için DYNAMIC_TIME_ZONE_INFORMATION veya TIME_ZONE_INFORMATION tipindeki parametrelerin içeriğini oluşturmamız gerekiyor. İçeriği oluşturabilmek için registry'de HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\ anahtarının altında ilgilendiğimiz ZamanDiliminin anahtarını bulmamız ve o anahtar altındaki registry value içeriklerini parametrelere doldurmamız gerekiyor. Örneğin, "GTB Standard Time" adlı ve şu anda Türkiye'deki çoğu bilgisayarda kullanılan zaman dilimi ile ilgili bilgiler HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\GTB Standard Time\ anahtarının altında bulunmaktadır. Buradan Yaz Saati adını Standart Zaman adını ve geçiş tarihlerini öğrenmemiz mümkün. Bu bilgileri aldıktan sonra SetDynamicTimeZoneInformation veya SetTimeZoneInformation fonksiyonlarını çağırabiliriz. Eğer geçiş zamanlarında değişiklik yapmak istersek bunu da yapmak mümkün gözüküyor. Dolayısıyla başta belirlediğimiz son özelliği de gerçekleştirebiliyoruz.

Uygulamaya ait tüm kaynak koda aşağıdaki ZDAyarlama.zip dosyasından ulaşabilirsiniz. İstediğiniz değişiklikleri yapıp derleyebilirsiniz. Kaynak koda mümkün olduğunca çok açıklama koymaya ve kullandığım referansları listelemeye çalıştım. Bu kaynakları kullanarak eminim sizler de ihtiyacınız doğrultusunda daha da güzel uygulamalar geliştirebilirsiniz.

Ben, uygulamayı sınırlı sürede geliştirip test ettim. Tüm olasılıkları veya yeterince çok olasılığı denediğimi söyleyemem. Amacım sadece işe yarayabilecek bir uygulamayı sizlerle paylaşmak. Gözlemlediğim iki nokta var :
#1 Windows Vista ve Windows 7'de uygulama doğru çalışsa dahi (Yaz Saatini, Pazartesi sabahına ötelemek) tarih zaman ayarlarına baktığınızda geçişin hala Pazar sabahı olacağına dair bir mesaj görüntüleniyor.
#2 Uygulamayı çalıştırırken tarih zaman ayarı penceresini kapatın. Windows XP/2003 Server'da bu pencere açıkken değişikliğin başarılı olmuş gibi gözükmesine rağmen istenilen zamanda Yaz Saatine geçişin gerçekleşmediğini gördük. Pencereyi kapattıktan sonraki denemelerimizde sonucun olumlu olduğunu gözlemledik. Fonksiyonların açıklamalarında tavsiye edilen WM_SETTINGCHANGE mesjını yollamadım. Bu yolla açık pencerelerin güncellenmesi de mümkün olabilir. İsterseniz bu özellikleri de ekleyebilirsiniz.

Kaynak kodunu, Microsoft'un sitesinden indirebileceğiniz Visual Studio Express versiyonları ile de derleyebilirsiniz. Eğer derlenmiş versiyonu kullanmak isterseniz ekteki sıkıştırılmış dosya içindeki stz.exe'yi kullanabilirsiniz.

Uygulamayı kullanmak

Uygulamanın alabileceği 3 tip parametre mevcut :

#1 ZamanDiliminin adını verirseniz sistemin zaman dilimini belirttiğiniz dilime ayarlar.

Örneğin, sistemin kullandığı ZamanDilimini Mısır'ınkine ayarlamak için :

H:\ ZDAyarlama>stz.exe "Egypt Standard Time"
Zaman Dilimi degisikligi basariyla tamamlandi
Standart Zamana Gecis Gunu : Eylul ayinin son Persembe gunu saat 23:59
Yaz Saatine Gecis Gunu : Nisan ayinin son Persembe gunu saat 23:59

Aslında Mısır zaman dilimi geçici olarak kullanmak için oldukça uygun bir zaman dilimi. Çünkü, yılın uzunca bir süresinde aynı saatte yer alıyoruz. Ayrıca, Mısır'da Yaz Saati geçişi Nisan sonuna doğru olacağı için GTB veya Turkey (yamayla birlikte yayınlanacak) zaman dilimine Pazartesi günü rahatlıkla geri alabilirsiniz. Tekrar GTB zaman dilimine geçmek için aşağıdaki şekilde uygulamayı çalıştırabilirsiniz :

H:\>ZDAyarlama\stz.exe "GTB Standard Time"
Zaman Dilimi degisikligi basariyla tamamlandi
Standart Zamana Gecis Gunu : Ekim ayinin son Pazar gunu saat 04:00
Yaz Saatine Gecis Gunu : Mart ayinin son Pazar gunu saat 03:00

#2 Hem zaman dilimini atamak hem de yaz saati uygulamasını Pazartesi sabahı (Mart ayının son) başlatmak için uygulamayı aşağıdaki şekilde kullanabilirsiniz. Ötelemeyi gerçekleştirmek için -pazartesi  parametresini uyguluyoruz.

H:\ ZDAyarlama>stz.exe "GTB Standard Time" -pazartesi
Zaman Dilimi degisikligi basariyla tamamlandi
Standart Zamana Gecis Gunu : Ekim ayinin son Pazar gunu saat 04:00
Yaz Saatine Gecis Gunu : Mart ayinin son Pazartesi gunu saat 03:00

#3 Hem zaman dilimini atamak hem de yaz saati uygulamasını eski haline yani Mart ayının son Pazar gününe geri getirmek için -pazar parametresini uygulayabiliriz.

H:\ZDAyarlama>stz.exe "GTB Standard Time" -pazar
Zaman Dilimi degisikligi basariyla tamamlandi
Standart Zamana Gecis Gunu : Ekim ayinin son Pazar gunu saat 04:00
Yaz Saatine Gecis Gunu : Mart ayinin son Pazar gunu saat 03:00

Tüm bu bilgilerin işinize yaraması ümidiyle.

-faik

ZDAyarlama.zip