TimeZone — iOS və macOS-da Foundatıon sinfi olub, saat qurşaqları haqqında məlumatı ümumiləşdirərək vaxtın coğrafi bölgələr arasında düzgün çevrilməsi üçün istifadə olunur. Apple Developer Documentation, 2024 məlumatına görə, TimeZone saat qurşağı identifikatorları (IANA Time Zone Database), UTC-yə nisbətən yerdəyişmə və yay vaxtına keçid qaydaları ilə işləmək üçün metodlar təqdim edir. Sinif DateFormatter və Calendar ilə inteqrasiya olunaraq tarixlərin formatlaşdırılması zamanı düzgün saat qurşağının avtomatik tətbiqini təmin edir. Əl ilə yerdəyişmənin əl ilə hesablanmasından fərqli olaraq, TimeZone cihazın saat qurşağı dəyişəndə məlumatları avtomatik yeniləyir.
Əsas məqamlar
TimeZone — Swift-də coğrafi saat qurşağı haqqında məlumat verən value tipidir: UTC-yə nisbətən yerdəyişmə, ad, abbreviatura və yay vaxtına keçid qaydaları. Objective-C-də sinif NSTimeZone adlanır. Hər iki sinif 1970-ci ildən bəri saat qurşaqlarının dəyişiklik tarixini əhatə edən IANA Time Zone Database-ə (Olson bazası kimi də tanınır) əsaslanır.
Hər bir TimeZone nümunəsi saat qurşağı identifikatorunu (məsələn, Europe/Moscow), UTC-dən saniyələrlə cari yerdəyişməni, isDaylightSavingTime bayrağını və növbəti keçid tarixini saxlayır. Identifikator əsas açardır: TimeZone(identifier:) ilə başlatma zamanı sistem cihazın saat qurşağı verilənlər bazasından müvafiq qeydi yükləyir.
IANA (2024) məlumatına görə, verilənlər bazası 600-dən çox unikal saat qurşağı identifikatorunu əhatə edir. Apple iOS və macOS-un hər versiyasında bu bazanın bir hissəsini təqdim edir ki, bu da şəbəkə sorğularına ehtiyac olmadan bütün cihazlarda hesablamaların vəhdiliyini təmin edir.
Arxitektura — Foundation-da TimeZone iki səviyyəli sistem üzərində qurulmuşdur: saat qurşağı identifikatoru (insan tərəfindən oxuna bilən ad) və onun rəqəm təmsili (UTC-dən yerdəyişmə). Sistem cihazın parametrlərindən cari saat qurşağını avtomatik seçir, lakin tərtibatçı onu xüsusi formatlaşdırma əməliyyatları üçün dəyişdirə bilər.
TimeZone Calendar və DateFormatter ilə sıx əlaqəlidir. Tarixin formatlaşdırılması zamanı DateFormatter vaxtın mütləq anını (Date) müvafiq saat qurşağında mətn təmsilinə çevirmək üçün TimeZone nümunəsinin timeZone xüssiyyətindən istifadə edir. timeZone təyin edilməyibsə, standart sistem saat qurşağı — TimeZone.current istifadə olunur.
| Növ | Başlatma | Xüsusiyyətlər |
|---|---|---|
| Cari | TimeZone.current | Parametrlərdə bölgə dəyişəndə avtomatik yenilənir, yay vaxtını izləyir |
| Sabit | TimeZone(identifier:) | Cihazın bölgəsindən asılı deyil. Seçilmiş identifikatoru daimi tətbiq edir |
| UTC | TimeZone(secondsFromGMT: 0) | Korreksiyasız saat qurşağı. Identifikator: GMT |
| İxtiyari yerdəyişmə ilə | TimeZone(secondsFromGMT: 10800) | Saniyələrlə sabit yerdəyişmə. Yay vaxtını nəzərə almır |
Vacib nüans: TimeZone(identifier:) naməlum identifikatorlar üçün nil qaytarır. Bu, tətbiqin çökməsinin tez-tez rast gəlinən səbəbidir — tərtibatçılar istifadəçi daxil etməsindən səhv identifikator ötürərək opsional dəyəri idarə etməyi unudurlar. IANA identifikatorları üçün registr əhəmiyyətlidir: Europe/Moscow — düzgün, europe/moscow — nil.
IANA Time Zone Database “Region/Şəhər” (Continent/City) formatından istifadə edir, burada region qitələrdən biridir (Africa, America, Asia, Atlantic, Australia, Europe, Indian, Pacific) və ya okean, şəhər isə saat qurşağı zonasındakı ən böyük yaşayış məntəqəsidir. Bu format identifikatorun unikallığını və oxunaqlılığını təmin edir.
Əsas formatdan əlavə, TimeZone üç əlavə identifikasiya üsulunu dəstəkləyir: abbreviatura (MSK, EST, PST), üchɑrfli zaman zonası kodları (GMT, UTC) və rəqəm yerdəyişmələr (+0300, -0500). Bununla belə, abbreviaturalar qeyri-müəyyəndir: EST həm Eastern Standard Time (GMT-5), həm də Avstraliyada Eastern Summer Time (GMT+10) mənasını verə bilər. Apple yalnız IANA identifikatorlarından istifadə etməyi tövsiyə edir.
import Foundation
// Bütün məlum saat qurşağı identifikatorlarını əldə et
let allIdentifiers: [String] = TimeZone.knownTimeZoneIdentifiers
print("Ümumi saat qurşaqları: \(allIdentifiers.count)")
// Bölgəyə görə filtrlə
let europeZones = allIdentifiers.filter { $0.hasPrefix("Europe/") }
print("Avropa saat qurşaqları: \(europeZones)")
// Abbreviatura (istehsalat üçün tövsiyə olunmur)
if let moscowTimeZone = TimeZone(abbreviation: "MSK") {
print("GMT-dən MSK saniyələri: \(moscowTimeZone.secondsFromGMT())")
}
// Yerdəyişməyə görə identifikator tap
let utcPlus3 = TimeZone(secondsFromGMT: 10800)
print("İdentifikator: \(utcPlus3.identifier)")
Abbreviatura TimeZone.abbreviationDictionary bütün məlum saat qurşaqları üçün ixtisarları ehtiva edir, lakin bu lüğət unikallığa zəmanət vermir: PST açarı həm America/Los_Angeles, həm də Pacific/Pago_Pago-ya uyğun gələ bilər. İstehsalat kodunda həmişə IANA identifikatorlarından istifadə edin.
TimeZone yay və qış vaxtına keçidi (DST — Daylight Saving Time) bu tətbiq olunan bütün bölgələr üçün avtomatik nəzərə alır. Sistem hər bir saat qurşağı üçün dəqiq keçid tarixlərini əhatə edən IANA Time Zone Database-dən tarixi məlumatlardan istifadə edir. isDaylightSavingTime xüssiyyəti, əgər saat qurşağı hazırda yay vaxtındadırsa, true qaytarır.
nextDaylightSavingTimeTransition metodu növbəti keçidin tarixini öyrənməyə imkan verir ki, bu da gələcək hadisələrin planlaşdırılması üçün faydalıdır. Bu funksionallıq xüsusilə DST qaydalarının tez-tez dəyişdirildiyi Braziliya və Mərakeş kimi bölgələr üçün vacibdir — 2024-cü ilə qədər Braziliya hər il keçid tarixlərini dəyişirdi və əl ilə hesablama tətbiqlərdə səhvlərə səbəb olurdu.
Apple WWDC 2023 məlumatına görə, Foundation-ın əsasındakı ICU (International Components for Unicode) kitabxanası iOS-un hər yenilənməsində DST məlumatlarını yeniləyir. Tətbiqlər yay vaxtı haqqında məlumatları sistem yenilənməsindən sonra bir gündən artıq keşləməməlidir — IANA bazası saat qurşağı düzəlişləri vasitəsilə ƏS versiyasını yeniləmədən də dəyişə bilər.
import Foundation
// Europe/Moscow üçün DST yoxla
let moscow = TimeZone(identifier: "Europe/Moscow")!
let now = Date()
let isMoscowDST = moscow.isDaylightSavingTime(for: now)
print("Moskva hazırda DST-də: \(isMoscowDST)")
// Növbəti DST keçid tarixini əldə et
if let nextTransition = moscow.nextDaylightSavingTimeTransition(
after: now
) {
let dstOffset = moscow.daylightSavingTimeOffset(
for: nextTransition
)
print("Növbəti keçid: \(nextTransition), DST yerdəyişməsi: \(dstOffset)s")
}
// DST məlumatı ilə təhlükəsiz çevirmə
let newYork = TimeZone(identifier: "America/New_York")!
let offsetNY = newYork.secondsFromGMT(for: now)
print("NY cari yerdəyişməsi: \(offsetNY / 3600)h")
Kritik nüans: secondsFromGMT(for:) müəyyən tarix üçün DST-ni nəzərə alır, secondsFromGMT() isə yalnız cari vaxt üçün. Tarixi tarixlərin formatlaşdırılması zamanı həmişə Date parametri ilə versiyadan istifadə edin: secondsFromGMT(for: someHistoricalDate). Fərq 1–2 saata çata bilər ki, bu da loglar və ya tarixi məlumatlar üçün kritikdir.
Tarixin formatlaşdırılması müəyyən saat qurşağı ilə — TimeZone ilə i\u015fl\u0259y\u0259rk\u0259n ən çox rast gəlinən tapşırıq. DateFormatter Date-i mətnə çevirmək üçün timeZone xüssiyyətindən istifadə edir. timeZone açıqca təyin edilməyibsə, formatlayıcı TimeZone.current — istifadəçinin cihazında qurulmuş saat qurşağından istifadə edir ki, bu da server məlumatları üçün gözlənilən nəticələrə səbəb ola bilər.
import Foundation
// Tarixi müəyyən saat qurşağında formatla
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let tokyo = TimeZone(identifier: "Asia/Tokyo")!
formatter.timeZone = tokyo
let tokyoTime = formatter.string(from: Date())
print("Tokio vaxtı: \(tokyoTime)")
// Istifadəçi seçimi üçün mövcud identifikatorlar
let displayNames: [(String, String)] = TimeZone.knownTimeZoneIdentifiers
.prefix(20)
.map { ($0, TimeZone(identifier: $0)!.localizedName(
for: .generic, locale: .current
)) }
// İki saat qurşağını müqayisə et
let london = TimeZone(identifier: "Europe/London")!
let difference = tokyo.secondsFromGMT(for: Date())
- london.secondsFromGMT(for: Date())
print("Tokio-London fərqi: \(difference / 3600)h")
// Abbreviatura lüğəti ilə işlə
let knownAbbrevs = TimeZone.abbreviationDictionary
for (abbr, ident) in knownAbbrevs.sorted(by: { $0.key < $1.key }).prefix(5) {
print("\(abbr) -> \(ident)")
}
Yerləşdirilmiş ad — localizedName(for:locale:) vasitəsilə saat qurşağının müəyyən dildə oxuna bilən adını qaytarır. Məsələn, Europe/Moscow üçün rus lokalı ilə metod “Moskva”, ingilis lokalı ilə isə “Moscow Time” qaytarır. Aşağıdakı stillər mövcuddur: .standard (standart ad), .daylightSaving (yay vaxtı) və .shortGeneric (qısa).
import Foundation
let paris = TimeZone(identifier: "Europe/Paris")!
let nameRU = paris.localizedName(
for: .standard,
locale: Locale(identifier: "ru_RU")
)
print("Rus adı: \(nameRU)")
// Bölgənin eyni gündə olub-olmadığını yoxla
let isSameDay = Calendar.current.isDate(
Date(),
equalTo: Date(),
toGranularity: .day
)
print("Müxtəlif saat qurşaqlarında eyni gün: \(isSameDay)")
Serializasiya — saat qurşağı identifikatorunun saxlanması TimeZone-u verilənlər bazalarında və ya UserDefaults-da saxlamaq üçün ən yaxşı təcrübədir. Saniyələrlə yerdəyişməni və ya abbreviatura deyil, identifikatoru (Europe/Moscow tipli sətri) saxlayın. Yerdəyişmə DST dəyişikliyi ilə dəyişə bilər, abbreviatura isə qeyri-müəyyəndir. Bərpa: TimeZone(identifier: savedString).
Sabit yerdəyişmənin istifadəsi saat qurşağı identifikatoru əvəzinə — ən çox yayılmış səhvdir. TimeZone(secondsFromGMT: 10800) DST-ni nəzərə almır, buna görə Europe/Moscow üçün yayda bu konstruksiya 1 saat səhv yerdəyişmə verir. Yay vaxtı olan bölgələr üçün həmişə IANA identifikatorundan istifadə edin.
Unudulmuş nil idarəetməsi TimeZone(identifier:) başlatması zamanı — ikinci ən çox rast gəlinən səhv. İstifadəçi səhv identifikator daxil edərsə (məsələn, “moscow” əvəzinə “Europe/Moscow”), konstruktor nil qaytarır. Opsional dəyəri idarə etmədən tətbiq runtime error ilə çökür. guard let və ya məlum fallback ilə TimeZone(identifier:) istifadə edin.
Gələcək tarixlərlə işlərkən DST-yə məhəl qoymama. TimeZone.secondsFromGMT(for:) — müəyyən tarix üçün yerdəyişməni almağın yeganə düzgün üsuludur. Parametrsiz secondsFromGMT() istifadəsi tarixi və ya gələcək tarixlər üçün cari anın yerdəyişməsini verir ki, bu da xüsusilə DST ləğv edilmiş və ya tətbiq edilmiş bölgələrdə göstərilən tarixdəki real yerdəyişməyə uyğun gəlməyə bilər.
Stack Overflow (2024) məlumatına görə, DateFormatter ilə bağlı sualların təxminən 15%-i timeZone-un səhv qurulması ilə bağlıdır. Tipik ssenari: server UTC-də tarix göndərir, tərtibatçı formatlayıcının timeZone-unu təyin etmədən onu formatlaşdırır və tarix cihazın saat qurşağında göstərilir, bu da müxtəlif bölgələrdən istifadəçilər arasında qarışıqlıq yaradır. Qayda: server məlumatları üçün həmişə formatlayıcının timeZone-unu açıqca təyin edin.
Tez-tez verilən suallar
TimeZone — iOS və macOS-da saat qurşaqları ilə işləmək üçün Foundation sinfi. O, UTC-yə nisbətən yerdəyişmə, yay vaxtına keçid qaydaları və IANA Time Zone Database əsasında saat qurşağı identifikatorları haqqında məlumat verir.
Üç format: IANA identifikatorları (Europe/Moscow), abbreviatura (MSK, EST) və rəqəm yerdəyişmələr (+0300). Apple istehsalat kodunda yeganə birmənalı format kimi IANA identifikatorlarından istifadə etməyi tövsiyə edir.
Avtomatik — secondsFromGMT(for:) və isDaylightSavingTime(for:) metodları vasitəsilə. TimeZone iOS-un hər buraxılışında yenilənən IANA tarixi məlumatlarından istifadə edir ki, bu da istənilən tarix üçün düzgün DST keçidlərini təmin edir.
TimeZone.current istifadəçinin parametrlərdə seçdiyi saat qurşağını qaytarır (coğrafi yerdən fərqlənə bilər). TimeZone.system cihazın saat qurşağını qaytarır, o, avtomatik olaraq geomoövqeyə görə müəyyən edilir və istifadəçi tərəfindən dəyişdirilə bilməz.
TimeZone.current cihazın cari saat qurşağını qaytarır. İdentifikatoru əldə etmək üçün identifier xüssiyyətindən istifadə edin: TimeZone.current.identifier. Yerləşdirilmiş ad üçün localizedName(for:locale:) metodunu çağırın.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun