ISO8601DateFormatter: asosiy tushunchalar va ISO 8601 formatlash

Muallif: IT Sectr Nashr etilgan: 2026-07-13 O'qish vaqti: 9 daq

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 — ISO 8601 standarti bo'yicha sanalarni formatlash uchun Foundation sinifi
  • DateFormat talab qilmaydi — format variantlar sozlamalari bo'yicha avtomatik aniqlanadi
  • Mahalliy sozlamalardan mustaqil — Locale sozlamasisiz barcha qurilmalarda bir xil ishlaydi
  • Millisekundlarni qo'llab-quvvatlash — har qanday aniqlikdagi sekund kasrlarini qayta ishlaydi (uch, olti va undan ko'p belgilar)
  • Formatlash variantlari — withFullDate, withTime, withMilliseconds, withTimeZone va boshqalar chiqish komponentlarini boshqaradi

ISO8601DateFormatter nima?

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.

ISO8601DateFormatter Foundation da qanday ishlaydi?

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.

VariantTavsifChiqish namunasi
.withFullDateYil, oy, kun2024-07-21
.withTimeSoat, daqiqa, sekund14:30:00
.withMillisecondsSekund kasrlari (3 belgigacha).123
.withFractionalSecondsSekund kasrlari (har qanday aniqlik).123456
.withTimeZoneVaqt mintaqasi+03:00
.withColonSeparatorInTimeZoneVaqt mintaqasida : ajratgichi+03:00 (+0300 o'rniga)
.withInternetDateTimeTo'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.

ISO 8601 format sozlamalari

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.

Asosiy variant kombinatsiyalari

  • .withFullDate — faqat sana: 2024-07-21. YYYY-MM-DD ko'rinishidagi satrlarni pars qilish uchun
  • .withFullDate + .withTime — vaqt mintaqasisiz sana va vaqt: 2024-07-21T14:30:00
  • .withInternetDateTime — to'liq format: 2024-07-21T14:30:00Z yoki 2024-07-21T14:30:00+03:00
  • .withInternetDateTime + .withFractionalSeconds — sekund kasrlari bilan: 2024-07-21T14:30:00.123456+00:00
  • .withFullDate + .withTime + .withTimeZone — tz da ikki nuqtasiz to'liq format: 2024-07-21T14:30:00+0300

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.

swift
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)")
}

Swift da ISO8601DateFormatter: kod misollari

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.

swift
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.

swift
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.

ISO 8601 uchun DateFormatter bilan solishtirish

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.

ParametrISO8601DateFormatterDateFormatter
Locale sozlamasiTalab qilinmaydi (e'tiborsiz qoldiradi)en_US_POSIX majburiy
DateFormatAvtomatik (variantlar orqali)Qo'lda format satri
Kasr sekundlarHar qanday aniqlik (.withFractionalSeconds)Ruxsat etilgan SSS
Z qo'shimchasiTo'g'ri qayta ishlaydiDateFormat orqali
UnumdorlikYuqori (ixtisoslashtirilgan)Past (umumiy)
StandartFaqat ISO 8601Har qanday format
iOS versiyasiiOS 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.

ISO 8601 pars qilishda odatdagi xatolar

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 nima?

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 DateFormatter dan nima bilan farq qiladi?

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.

O'zgaruvchan uzunlikdagi kasr sekundlarni qanday boshqarish kerak?

.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.

ISO8601DateFormatter qaysi vaqt mintaqasidan foydalanadi?

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.

Nega vaqtsiz sanani pars qilish nil qaytaradi?

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

  • ISO8601DateFormatter — ISO 8601 uchun ixtisoslashtirilgan sinif, DateFormatter dan xavfsizroq va sodda
  • Format variantlari qo'lda dateFormat ni almashtiradi — .withFullDate, .withTime, .withTimeZone ni birlashtiring
  • Locale ga bog'liq emas — locale sozlamasisiz barcha qurilmalarda bir xil pars qiladi
  • .withFractionalSeconds har qanday aniqlikdagi sekund kasrlarini qayta ishlaydi (1–9 belgi)
  • DateFormatter yutqazadi ISO 8601 vazifalari uchun unumdorlik, xavfsizlik va soddalikda
  • Variant chalkashligi — withMilliseconds va withFractionalSeconds almashtirib bo'lmaydi
  • Sekundsiz format (2024-07-21T14:30+03:00) qo'llab-quvvatlanmaydi — DateFormatter kerak

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.

Loyihani muhokama qilish

Shuningdek o'qing