1. Giriş
Əgər sən düşünürsən ki, zaman zonaları sadəcə "neçə saat əlavə et/çıxart" deməkdir, çox tezliklə planetdəki əksər proqramçıların ağrısını hiss edəcəksən. Zaman zonaları, saatların yay/qış vaxtına keçirilməsi, "vaxtı başqa regiona çevirmək" cəhdində gözlənilməz istisnalar — bunların hamısı tapmaq çətin olan və istifadəçiyə izah etmək daha da çətin olan bug-lara səbəb ola bilər.
Ən dəhşətlisi: dünyada heç vaxt "universal" vaxt anlayışı olmayıb — məsələn, iki qonşu ölkə yay vaxtına keçidə fərqli yanaşa bilər, bəzən isə bu qərarlar ilin ortasında qəbul olunur (bəli, bu həqiqətən belədir!). Məsələn: 2011-ci ildə Samoa bir günü "atladı" və tarix dəyişmə xəttinin digər tərəfinə keçdi.
Amma C# və .NET bizə güclü alətlər verir, bununla heç olmasa bir az mübarizə aparmaq üçün. Bu gün biz xilaskarımızla — TimeZoneInfo tipi və onun funksiyaları ilə tanış olacağıq, hansılar ki, sənə və sənin tətbiqinə kömək edəcək.
Zaman zonaları ilə işləmək sənə nə vaxt və niyə lazımdır
- İstifadəçilər/serverlər dünyanın müxtəlif regionlarındadırsa
- Tarix və vaxtı bazada UTC ilə saxlayırsansa, amma istifadəçiyə onun lokal vaxtında göstərirsənsə
- Cədvəllərin, xatırlatmaların, onlayn tədbirlərin hesablanması üçün ("Vebinar Berlin vaxtı ilə 19:00-da başlayacaq — bəs sənin regionunda?")
- Korporativ/qlobal sistemlər hazırlayanda (məsələn, beynəlxalq biznes üçün mühasibatlıq və ya CRM)
TimeZoneInfo tipinə ümumi baxış
TimeZoneInfo — .NET-də xüsusi yaradılmış bir sinifdir, zaman zonası haqqında məlumatı təqdim etmək üçündür: UTC-yə nisbətən ofseti, adı, yay vaxtına keçidi dəstəkləyib-dəstəkləməməsi və s.
Köhnə TimeZone sinifindən fərqli olaraq, hansı ki, yalnız "lokal" və "UTC" zaman zonalarını tanıyır, TimeZoneInfo sənə sistemdə qeydiyyatdan keçmiş bütün zaman zonalarına (hətta əl ilə yaradılmışlara belə) tam çıxış verir.
2. Zaman zonaları haqqında məlumat almaq
Lokal və UTC zonalar
Lokal zaman zonası haqqında məlumat almaq çox asandır:
// Lokal (yəni proqramın indi işlədiyi yer)
TimeZoneInfo local = TimeZoneInfo.Local;
// Həmişə UTC
TimeZoneInfo utc = TimeZoneInfo.Utc;
Console.WriteLine(local.DisplayName); // Məsələn: (UTC+01:00) Berlin, Vienna
Console.WriteLine(utc.DisplayName); // (UTC) Coordinated Universal Time
Bütün mövcud zaman zonaları
Çox vaxt istifadəçiyə bütün mümkün zaman zonalarının siyahısını göstərmək lazımdır (məsələn, servisdə qeydiyyat zamanı):
foreach (var tz in TimeZoneInfo.GetSystemTimeZones())
{
Console.WriteLine($"{tz.Id} | {tz.DisplayName}");
}
Bu, belə bir siyahı çıxaracaq:
- Central European Standard Time | (UTC+01:00) Berlin, Vienna
- Pacific Standard Time | (UTC-08:00) Pacific Time (US & Canada)
- və s.
Vizualizasiya: TimeZoneInfo əsas xüsusiyyətləri
| Xüsusiyyət | Təsviri |
|---|---|
|
Zaman zonasının sistem identifikatoru (axtarış üçün istifadə olunur) |
|
İstifadəçi üçün təsvir (saat və şəhərlərlə) |
|
"Adi" vaxtın adı |
|
Yay vaxtına keçid üçün vaxtın adı |
|
UTC-dən ofset (məsələn, Berlin üçün +01:00) |
|
True, əgər zaman zonası yay/qış vaxtına keçidi dəstəkləyirsə |
3. Zaman zonaları arasında vaxt çevirmə
Bax, bütün bu işlər bunun üçün idi! Sənə lazımdır:
- Vaxtı bir zonadan digərinə çevirmək (məsələn, server UTC-də yazıb, amma istifadəçiyə onun zonasına uyğun göstəririk)
- Yay/qış vaxtına keçidi düzgün işləmək
Ümumi sintaksis
DateTime utcNow = DateTime.UtcNow;
// Məsələn, bu vaxtı Mərkəzi Avropa zaman zonasına çevirək
TimeZoneInfo europeZone = TimeZoneInfo.FindSystemTimeZoneById("Central European Standard Time");
DateTime europeTime = TimeZoneInfo.ConvertTimeFromUtc(utcNow, europeZone);
Console.WriteLine($"UTC indi: {utcNow}"); // 2024-06-20 10:30:00
Console.WriteLine($"Avropa indi: {europeTime}"); // 2024-06-20 11:30:00
Vacibdir: Həmişə daxili hesablamalar və saxlama üçün UTC istifadə et, və yalnız "çıxışda" lazım olan zonaya çevir!
Zaman zonasının identifikatorunu necə tapmaq olar?
Windows-da identifikatorlar (Id) spesifikdir (məsələn, "Central European Standard Time"), Linux/Unix-də isə adətən IANA/Olson identifikatorlarıdır ("Europe/Berlin", "America/New_York").
Sənin sistemində identifikatorların siyahısını TimeZoneInfo.GetSystemTimeZones() ilə əldə edə bilərsən.
4. İstənilən zonalar arasında çevirmə
Tutaq ki, sən Londonda (GMT/UTC+0) vaxt almısan və onu Tokyoya (UTC+9) çevirmək istəyirsən:
DateTime londonTime = new DateTime(2024, 6, 20, 12, 0, 0, DateTimeKind.Unspecified);
TimeZoneInfo londonZone = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
TimeZoneInfo tokyoZone = TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time");
// Birinci addım: vaxtı UTC-yə çevir (əgər lokal vaxtdırsa)
DateTime utc = TimeZoneInfo.ConvertTimeToUtc(londonTime, londonZone);
// İkinci addım: UTC-ni Tokio vaxtına çevir
DateTime tokyoTime = TimeZoneInfo.ConvertTimeFromUtc(utc, tokyoZone);
Console.WriteLine($"London: {londonTime} | UTC: {utc} | Tokyo: {tokyoTime}");
Yay və qış vaxtına keçidlərlə işləmək
TimeZoneInfo yay/qış vaxtına keçidləri nəzərə alır — əgər həmin zona onları dəstəkləyirsə.
TimeZoneInfo eastern = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
DateTime dateWinter = new DateTime(2024, 1, 1, 12, 0, 0, DateTimeKind.Unspecified);
DateTime dateSummer = new DateTime(2024, 7, 1, 12, 0, 0, DateTimeKind.Unspecified);
Console.WriteLine( TimeZoneInfo.ConvertTimeToUtc(dateWinter, eastern)); // UTC-5 ofseti
Console.WriteLine( TimeZoneInfo.ConvertTimeToUtc(dateSummer, eastern)); // UTC-4 ofseti — yay vaxtı!
Hətta ABŞ (yuxarıdakı nümunədə) yay vaxtına keçiddən imtina etsə belə (belə təşəbbüslər hər il olur!), sənin əməliyyat sistemində zaman zonalarının bazası yenilənəcək və kodun düzgün işləyəcək.
5. Praktiki məsləhətlər və tez-tez rast gəlinən səhvlər
İstisnalar və gizli tələlər
- Saatların dəyişdiyi yerdə (məsələn, yay/qış vaxtına keçid gecəsi 2:30-da), bəzi vaxtlar "mövcud olmayan" və ya "təkrarlanan" ola bilər:
Məsələn, "geri" keçid günündə 2:30 iki dəfə olur — və hər ikisi "fərqli"dir. - Unutma: zaman zonalarının siyahısı əməliyyat sisteminin yenilənməsi ilə dəyişə bilər! Məsələn: bəzi ölkələr yay vaxtına keçidi ləğv edir və ya tətbiq edir.
GO TO FULL VERSION