ISO8601DateFormatter — iOS va macOS da Foundation sinifi bo'lib, xalqaro ISO 8601 standartida sanalarni formatlash va pars qilish uchun mo'ljallangan. Apple Developer Documentation, 2024 ga ko'ra, ISO8601DateFormatter DateFormatni qo'lda o'rnatmasdan millisekundlar, vaqt mintaqalari va sekund kasrlari bilan formatlarni avtomatik qayta ishlaydi. DateFormatter dan farqli o'laroq, bu sinif Locale va TimeZone ga bog'liq emas — u ISO 8601 spetsifikatsiyasiga qat'iy rioya qiladi, bu esa uni server va mijoz o'rtasida sana almashish uchun ideal qiladi. Sinif iOS 10 va macOS 10.12 dan boshlab mavjud.
Asosiy nuqtalar
ISO8601DateFormatter — Foundation dagi Formatter ning ixtisoslashtirilgan osti sinifi bo'lib, Date va ISO 8601 formatidagi satr o'rtasida ikki tomonlama konvertatsiyani amalga oshiradi. ISO 8601 standarti (International Standard for the Representation of Dates and Times) sana va vaqt almashish uchun xalqaro formatni belgilaydi: 2024-07-21T14:30:00+00:00. DateFormatter dan farqli o'laroq, bu sinif dateFormat ko'rsatishni talab qilmaydi va berilgan variantlar asosida satr strukturasini avtomatik aniqlaydi.
ISO8601DateFormatter ning DateFormatter ga nisbatan asosiy afzalliklari: locale ga bog'liqlik yo'qligi (pars qilish har qanday qurilmada bir xil ishlaydi), sekund kasrlarining o'rnatilgan qo'llab-quvvatlashi (verguldan keyin istalgan sonli belgilar bilan) va uzatilgan variantlar asosida formatni avtomatik aniqlash. Sinif shuningdek Z qo'shimchasini (UTC belgisi), +HH:mm formatidagi vaqt mintaqalarini va kamaytirilgan aniqlikni (vaqtsiz faqat sana) to'g'ri qayta ishlaydi.
ISO Specification (ISO 8601-1:2019) ga ko'ra, standart to'rtta aniqlik darajasini qo'llab-quvvatlaydi: yil (2024), yil-oy (2024-07), to'liq sana (2024-07-21) va vaqt mintaqasi bilan sana-vaqt (2024-07-21T14:30:00+00:00). ISO8601DateFormatter format variantlari kombinatsiyasi orqali bu barcha darajalarni qamrab oladi va dasturchini dateFormat satrini qo'lda yozishdan ozod qiladi.
Ishlash prinsipi ISO8601DateFormatter bit variantlari (formatOptions) kombinatsiyasiga asoslanadi, ularning har biri chiqishda ma'lum sana yoki vaqt komponentini faollashtiradi. Masalan, .withFullDate varianti yil, oy va kunni faollashtiradi; .withTime — soat, daqiqa va sekundlarni. Variantlarni birlashtirib, dasturchi dateFormat satrini yozmasdan kerakli aniqlik darajasini oladi.
Ichki tarzda ISO8601DateFormatter pars qilish uchun ICU kutubxonasidan foydalanadi, lekin qat'iy ISO 8601 qoidalari bilan. Bu shuni anglatadiki, u qurilmada o'rnatilgan Locale va TimeZone sozlamalarini e'tiborsiz qoldiradi — natija har doim bashorat qilinadi. Vaqt mintaqasini o'rnatish uchun timeZone xususiyati ishlatiladi, odatda UTC ga teng. timeZone nil ga o'rnatilgan bo'lsa, qurilmaning mahalliy vaqti ishlatiladi.
| Variant | Tavsif | Chiqish namunasi |
|---|---|---|
| .withFullDate | Yil, oy, kun | 2024-07-21 |
| .withTime | Soat, daqiqa, sekund | 14:30:00 |
| .withMilliseconds | Sekund kasrlari (3 belgigacha) | .123 |
| .withFractionalSeconds | Sekund kasrlari (har qanday aniqlik) | .123456 |
| .withTimeZone | Vaqt mintaqasi | +03:00 |
| .withColonSeparatorInTimeZone | Vaqt mintaqasida : ajratgichi | +03:00 (+0300 o'rniga) |
| .withInternetDateTime | To'liq format (date + time + tz) | 2024-07-21T14:30:00+00:00 |
Variantlarni birlashtirish: .withInternetDateTime .withFullDate, .withTime va .withTimeZone ning birlashmasiga teng. Millisekundli satrlarni pars qilish uchun .withFractionalSeconds qo'shing. Yodda tutish muhimki, .withMilliseconds sekund kasrlarini uch belgi bilan cheklaydi, .withFractionalSeconds esa har qanday aniqlikni qo'llab-quvvatlaydi — verguldan keyin birdan to'qqiz raqamgacha.
Format variantlari ISO8601DateFormatter uch guruhga bo'linadi: sana komponentlari (withFullDate, withYear, withMonth, withDay, withWeekOfYear), vaqt komponentlari (withTime, withHours, withMinutes, withSeconds) va qo'shimcha sozlamalar (withMilliseconds, withFractionalSeconds, withTimeZone, withColonSeparatorInTimeZone, withDashSeparatorInDate, withFullTime). Ularni birlashtirib, ISO 8601 ning deyarli istalgan osti formatini olish mumkin.
Muhim nuance: .withFractionalSeconds va .withMilliseconds o'zaro istisno qiladi — ikkalasi o'rnatilgan bo'lsa, .withFractionalSeconds qo'llaniladi. Server ma'lumotlaridan millisekundlarni pars qilish uchun .withFractionalSeconds tavsiya etiladi, chunki ko'p serverlar sekund kasrlarini uch, olti yoki to'qqiz belgi bilan yuboradi va .withFractionalSeconds har qanday uzunlikni qayta ishlaydi.
import Foundation
// ISO8601DateFormatter ni sozla
let formatter = ISO8601DateFormatter()
formatter.timeZone = TimeZone(secondsFromGMT: 0)
// Turli format variant kombinatsiyalari
formatter.formatOptions = [.withFullDate]
let dateOnly = formatter.string(from: Date())
print("Sana: \(dateOnly)")
formatter.formatOptions = [.withFullDate, .withTime]
let dateTime = formatter.string(from: Date())
print("DateTime: \(dateTime)")
formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
let full = formatter.string(from: Date())
print("To'liq: \(full)")
// Millisekundli satrni pars qil
let serverString = "2024-07-21T14:30:00.123456+03:00"
if let parsed = formatter.date(from: serverString) {
print("Pars qilindi: \(parsed)")
}
Asosiy foydalanish ISO8601DateFormatter dan foydalanish namuna yaratish, timeZone (server ma'lumotlari uchun UTC tavsiya etiladi) va formatOptions o'rnatishdan iborat, shundan so'ng formatlash uchun string(from:) va pars qilish uchun date(from:) chaqirish mumkin. DateFormatter dan farqli o'laroq, Locale haqida qayg'urish shart emas — sinif mintaqaviy sozlamalarni e'tiborsiz qoldiradi.
import Foundation
let formatter = ISO8601DateFormatter()
// Turli ISO 8601 formatlarini pars qil
let strings: [String] = [
"2024-07-21T14:30:00Z",
"2024-07-21T14:30:00+03:00",
"2024-07-21T14:30:00.123Z",
"2024-07-21"
]
for str in strings {
if let autoParsed = formatter.date(from: str) {
print("Pars qilindi '\(str)': \(autoParsed)")
} else {
// Faqat sana satrlari uchun withFullDate ni ishlat
formatter.formatOptions = [.withFullDate]
if let fallback = formatter.date(from: str) {
print("Fallback pars qilindi '\(str)': \(fallback)")
}
formatter.formatOptions = [.withInternetDateTime]
}
}
// RFC 3339 ga serializatsiya qil (GitHub API)
formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
let rfc3339 = formatter.string(from: Date())
print("RFC 3339: \(rfc3339)")
O'zgaruvchan uzunlikdagi kasr sekundli sanalarni pars qilish — ko'plab zamonaviy API larning xususiyati. Server ham 2024-07-21T14:30:00.123Z (3 belgi), ham 2024-07-21T14:30:00.123456Z (6 belgi) yuborishi mumkin. .withFractionalSeconds varianti bilan ISO8601DateFormatter ikkala variantni to'g'ri qayta ishlaydi, DateFormatter esa dateFormat = “yyyy-MM-dd’T’HH:mm:ss.SSSZ” bilan faqat uch raqamli millisekundlarni qayta ishlaydi.
import Foundation
let variantFormatter = ISO8601DateFormatter()
variantFormatter.formatOptions = [
.withInternetDateTime,
.withFractionalSeconds
]
// Turli kasr sekund aniqligi
let variants: [String] = [
"2024-07-21T14:30:00.1Z",
"2024-07-21T14:30:00.12Z",
"2024-07-21T14:30:00.123Z",
"2024-07-21T14:30:00.123456Z",
"2024-07-21T14:30:00.123456789Z"
]
for variant in variants {
if let parsed = variantFormatter.date(from: variant) {
print("OK: \(variant) -> \(parsed)")
} else {
print("FAIL: \(variant)")
}
}
// WithMilliseconds ni ishlat (faqat 3 raqam)
variantFormatter.formatOptions = [
.withInternetDateTime,
.withMilliseconds
]
let milliParsed = variantFormatter.string(from: Date())
print("Millisekundlar bilan: \(milliParsed)")
Barcha variantlarni pars qilishni sinash: yuqoridagi kod .withFractionalSeconds bilan ISO8601DateFormatter 1 dan 9 gacha bo'lgan istalgan uzunlikdagi sekund kasrlarini muvaffaqiyatli qayta ishlashini ko'rsatadi. Bu turli server platformalari bilan moslik uchun muhim: .NET ko'pincha 7 belgi (100 nanosekundlik tiklar), Python — 6, Java esa versiyasiga qarab 3 yoki 9 belgi yaratadi.
DateFormatter ham ISO 8601 ni pars qila oladi, lekin dateFormat, locale va timeZone ni qo'lda o'rnatishni talab qiladi. Asosiy muammo shundaki, DateFormatter Locale ga bog'liq va en_US_POSIX o'rnatilmasa, nostandart sana formatlari bo'lgan mintaqalardagi foydalanuvchilarda pars qilish buzilishi mumkin. ISO8601DateFormatter bu muammoni arxitektura darajasida hal qiladi: u Locale dan foydalanmaydi.
| Parametr | ISO8601DateFormatter | DateFormatter |
|---|---|---|
| Locale sozlamasi | Talab qilinmaydi (e'tiborsiz qoldiradi) | en_US_POSIX majburiy |
| DateFormat | Avtomatik (variantlar orqali) | Qo'lda format satri |
| Kasr sekundlar | Har qanday aniqlik (.withFractionalSeconds) | Ruxsat etilgan SSS |
| Z qo'shimchasi | To'g'ri qayta ishlaydi | DateFormat orqali |
| Unumdorlik | Yuqori (ixtisoslashtirilgan) | Past (umumiy) |
| Standart | Faqat ISO 8601 | Har qanday format |
| iOS versiyasi | iOS 10+ | iOS 2+ |
Qachon DateFormatter ishlatiladi: sanani ISO 8601 bo'lmagan formatda formatlash kerak bo'lsa (masalan, UI uchun „2024 yil 21 iyul”) yoki iOS 9 va eski versiyalarini qo'llab-quvvatlash talab qilinsa. Server bilan sana almashish bo'yicha barcha vazifalar uchun ISO8601DateFormatter dan foydalaning — u xavfsizroq, unumliroq va kamroq kod talab qiladi. ISO 8601 uchun DateFormatter locale va mintaqaviy sozlamalar bilan bog'liq potentsial xatolar manbaidir.
DateFormatter dan ISO8601DateFormatter ga migratsiya: DateFormatter yaratish + dateFormat + locale + timeZone sozlashni ISO8601DateFormatter yaratish + formatOptions + timeZone sozlash bilan almashtiring. Satrni pars qilish date(from:) orqali o'zgarishsiz qoladi. Orqaga moslik uchun #available(iOS 10, *) bilan DateFormatter ga fallback ishlatilishi mumkin.
Unutilgan formatOptions sozlamasi formatterning odatdagi qiymat — .withInternetDateTime ishlatishiga olib keladi. Server vaqtsiz faqat sana yuborsa (2024-07-21), pars qilish nil qaytaradi. Har doim formatOptions serverdan kelishi mumkin bo'lgan barcha formatlarni qamrab olishini tekshiring. O'zgaruvchan formatli API lar uchun turli variant kombinatsiyalari bilan fallback urinishlaridan foydalaning.
withMilliseconds va withFractionalSeconds ni chalkashtirish — sekund kasrlari bilan sanalarni pars qilishda tez-tez uchraydigan xato. withMilliseconds verguldan keyin aniq 3 raqam kutadi. Agar server 6 raqam (mikrosekundlar) yuborsa, withMilliseconds bilan pars qilish xato bilan tugaydi. Istalgan belgilar soni bilan moslik uchun .withFractionalSeconds dan foydalaning. .withFractionalSeconds iOS 13 da paydo bo'lgan; eski versiyalar uchun dateFormat bilan DateFormatter dan foydalaning.
Vaqt mintaqasini e'tiborsiz qoldirish — yana bir keng tarqalgan muammo. Agar server sana bilan vaqt mintaqasini yuborsa (+03:00), formatter esa UTC ga o'rnatilgan bo'lsa, pars qilish buzilmaydi, lekin natija UTC da bo'ladi. Dasturchilar ko'pincha Date vaqt mintaqasini saqlab qolishini kutishadi, lekin Date mutlaq vaqt momentidir va vaqt mintaqasi ma'lumotini saqlamaydi. To'g'ri ko'rsatish uchun vaqt mintaqasini alohida saqlang yoki to'g'ri timeZone bilan ISO8601DateFormatter dan foydalaning.
Apple Forum (2024) ga ko'ra, ISO8601DateFormatter bilan bog'liq savollarning taxminan 20% sekundlar ixtiyoriy bo'lgan formatga tegishli. ISO 8601 standarti sekundsiz formatga ruxsat beradi: 2024-07-21T14:30+03:00. .withInternetDateTime bilan ISO8601DateFormatter bu formatni qo'llab-quvvatlamaydi — uni pars qilish uchun dateFormat = “yyyy-MM-dd’T’HH:mmZ” bilan DateFormatter kerak bo'ladi. Bu cheklov qisqartirilgan vaqt formatidan foydalanadigan API lar bilan ishlashda hisobga olinishi kerak.
Tez-tez so'raladigan savollar
ISO8601DateFormatter — ISO 8601 formatida sanalarni formatlash va pars qilish uchun ixtisoslashtirilgan Foundation sinifi, iOS 10 dan boshlab mavjud. dateFormat ni qo'lda o'rnatmasdan standart formatlarni avtomatik qayta ishlaydi.
ISO8601DateFormatter Locale ga bog'liq emas, dateFormat o'rniga variantlardan foydalanadi va istalgan uzunlikdagi sekund kasrlarini to'g'ri qayta ishlaydi. DateFormatter universaldir, lekin qo'lda sozlashni talab qiladi va mintaqaviy sozlamalar bilan bog'liq xatolarga moyil.
.withFractionalSeconds variantidan foydalaning — verguldan keyin 1 dan 9 gacha belgini qo'llab-quvvatlaydi. Aniqlik farq qilishi mumkin bo'lsa, .withMilliseconds ishlatmang. .withFractionalSeconds iOS 13 dan boshlab mavjud.
Odatda UTC. O'zgartirish uchun timeZone xususiyatini o'rnating. Agar timeZone = nil bo'lsa, qurilmaning mahalliy vaqti ishlatiladi. +HH:MM formatida aniq vaqt mintaqasi bilan satrni pars qilishda formatter uni avtomatik hisobga oladi.
Chunki formatOptions odatda .withInternetDateTime, sana + vaqt + vaqt mintaqasini kutadi. Faqat sanani pars qilish uchun formatOptions = [.withFullDate] o'rnating. Ikkala variantni qo'llab-quvvatlash uchun turli variantlar bilan fallback dan foydalaning.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.