DateFormatter — Date obyektlari va ularning matn ko‘rinishi o‘rtasida ikki tomonlama konvertatsiya qilish uchun mo‘ljallangan Foundation sinfidir. Sinf foydalanuvchining lokalini, vaqt mintaqasi va kalendarini hisobga olib, dunyoning istalgan mintaqasida sanalarni to‘g‘ri ko‘rsatishni ta’minlaydi. Apple Developer Documentation (2025) ma’lumotlariga ko‘ra, DateFormatter to‘rtta oldindan belgilangan sana va vaqt uslubini, shuningdek, andoza satri orqali to‘liq moslashtirilgan formatlarni qo‘llab-quvvatlaydi. DateFormattersiz xalqaro ilovada foydalanuvchiga sanani to‘g‘ri ko‘rsatish mumkin emas.
Asosiy
DateFormatter — Foundation frameworkidan Date va matn o‘rtasida ikki tomonlama konvertatsiyani amalga oshiradigan sinf. U OpenStep da NSDateFormatter sifatida paydo bo‘lgan va shu vaqtdan boshlab barcha Apple platformalarida sanalarni formatlashning asosiy vositasi bo‘lib qolmoqda. Sinf Formatter dan meros oladi va lokalizatsiyalangan sana ko‘rinishi uchun qulay API ni taqdim etadi.
DateFormatter ning ishlash printsipi Unicode LDML shablonlariga asoslanadi — xuddi ICU (International Components for Unicode) da ishlatiladiganlar bilan bir xil. Shablon dateFormat xususiyati orqali belgilanadi, bu erda y, M, d, H, m, s belgilari mos ravishda yil, oy, kun, soat, daqiqa va soniyaga to‘g‘ri keladi. Belgining takrorlanishi formatni belgilaydi: “y” — ikki xonali yil, “yyyy” — to‘rt xonali.
DateFormatter yaratish qimmat operatsiya, chunki ishga tushirishda lokal va kalendar ma’lumotlari yuklanadi. Apple har bir formatlash turi uchun formatter bir marta yaratish va uni qayta ishlatishni tavsiya qiladi. SwiftUI va UIKit da formatterlar ko‘pincha statik xususiyatlarda keshlanadi yoki birinchi murojaatda erincha yaratiladi.
DateFormatter iOS ning ko‘plab tizim komponentlarida qo‘llaniladi. UIDatePicker countDownTimer rejimida sanalarni ko‘rsatish uchun ichki DateFormatter dan foydalanadi. Kirishda formatterga ega TextField foydalanuvchi kiritgan sanani avtomatik tekshirishi mumkin. Core Data Date turidagi atributlarni qo‘llab-quvvatlaydi, ammo ularning matn ko‘rinishi har doim DateFormatter orqali amalga oshiriladi.
Thread Safety — DateFormatter ip xavfsiz emas. Formatter xususiyatlarini turli iplardan o‘zgartirish noaniq xatti-harakatga olib keladi. Ko‘p ipli foydalanish uchun har bir ip uchun alohida formatter instansiyalarini yarating yoki NSLock yoki serial queue orqali sinxronizatsiyadan foydalaning.
dateStyle va timeStyle — sana ko‘rinishini sozlashning eng oddiy usullari. Har bir uslub to‘rtta variantga ega: .short, .medium, .long, .full. dateStyle va timeStyle kombinatsiyasi sana va vaqt formatini mustaqil sozlash imkonini beradi, .none xususiyati esa tegishli qismni o‘chiradi.
AQSh lokali uchun .short uslubi sanani “7/21/26” kabi, O‘zbek lokali uchun esa “21.07.2026” kabi formatlaydi. .long uslubi O‘zbek lokali uchun “21 iyul 2026”, .full esa “seshanba, 21 iyul 2026” kabi hafta kuni bilan ko‘rsatadi. Barcha to‘rtta uslublar avtomatik ravishda mintaqaviy standartlarga, jumladan komponentlar tartibi va ajratgichlarga moslashadi.
RelativeDateFormatter iOS 15+ da RelativeDateFormatter va DateIntervalFormatter orqali muqobil yondashuvni taklif qiladi. RelativeDateFormatter joriy kontekst uchun “bugun”, “kecha”, “3 kundan keyin” kabi ko‘rsatadi. DateIntervalFormatter sana oralig‘ini ko‘rsatadi: “21–25 iyul 2026” — bron qilish va rejalashtirish uchun.
| Uslub | Misol (uz_UZ) | Misol (en_US) |
|---|---|---|
| .short | 21.07.2026 | 7/21/26 |
| .medium | 21 iyl 2026 | Jul 21, 2026 |
| .long | 21 iyul 2026 | July 21, 2026 |
| .full | seshanba, 21 iyul 2026 | Tuesday, July 21, 2026 |
Uslublarni birlashtirganda DateFormatter avtomatik ajratgichni tanlaydi: .short.date + .short.time uchun natija “21.07.2026, 14:30” bo‘lishi mumkin. .full.date + .full.time uchun — “seshanba, 21 iyul 2026, 14:30:00 MSK”. Ajratgich lokal tomonidan boshqariladi, dasturchi tomonidan emas — bu foydalanuvchining mintaqaviy kutishlariga muvofiqlikni kafolatlaydi.
dateFormat Unicode LDML spetsifikatsiyasi belgilaridan foydalanib ixtiyoriy formatlash shablonini belgilash imkonini beradi. Bu ko‘rinish ustidan to‘liq nazorat beradi: faqat yil va oyni, raqamsiz hafta kunini yoki soniyasiz vaqtni ko‘rsatishingiz mumkin. Moslashtirilgan format dizaynning maxsus talablari uchun ajralmasdir.
Asosiy belgilar — yyyy (yil: 2026), MM (oy: 07), dd (kun: 21), HH (soat: 14), mm (daqiqa: 30), ss (soniya: 00). To‘liq oy nomi uchun MMMM (iyul), qisqartirilgan uchun MMM (iyl) foydalaning. Hafta kuni — EEEE (seshanba), qisqartirilgan — E (se).
dateFormat dan foydalanganda formatterning locale ini o‘rnatish muhimdir. Agar locale o‘rnatilmagan bo‘lsa, formatter tizim lokalidan foydalanadi, bu API da qat’iy format uchun keraksiz bo‘lishi mumkin. Apple qat’iy mintaqalararo format uchun locale = Locale(identifier: “en_US_POSIX”) o‘rnatishni tavsiya qiladi, ayniqsa server javoblaridan sanalarni tahlil qilishda.
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "ru_RU")
formatter.dateFormat = "d MMMM yyyy"
let customString = formatter.string(from: Date())
// "21 July 2026"
// Maxsus satrni tahlil qilish
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let date = formatter.date(from: "2026-07-21 14:30:00")!
dateFormatdagi xato — ilova ishdan chiqishining tez-tez uchraydigan sabablaridan biri. Agar format satrga mos kelmasa, date(from:) metodi nil qaytaradi. Ixtiyoriy qiymatni xavfsiz olish uchun guard let yoki ?? foydalaning. Formatni tekshirish uchun barcha qo‘llab-quvvatlanadigan tillarda sinab ko‘ring — ba’zi LDML belgilari turli lokallarda turlicha ishlaydi.
Locale oylar, hafta kunlari nomlari qanday ko‘rsatilishi va qanday ajratgichlar ishlatilishini belgilaydi. DateFormatter sukut bo‘yicha Locale.current dan foydalanadi, ammo ba’zi stsenariylarda aniq lokalni ko‘rsatish talab qilinadi: jurnallarda qat’iy format uchun en_US_POSIX, server sanalari uchun serverga mos lokalni foydalaning.
TimeZone xususiyati ko‘rsatish uchun vaqt mintaqasini belgilaydi. Sukut bo‘yicha tizim vaqt mintaqasi ishlatiladi, ammo xalqaro auditoriyaga ega ilovalarda sanalarni foydalanuvchining vaqt mintaqasida yoki UTC da ko‘rsatish talab qilinadi. timeZone ni o‘zgartirish faqat ko‘rinishga ta’sir qiladi — Date qiymati o‘zgarmas qoladi.
Muhim xususiyat: agar DateFormatter satrni tahlil qilish uchun ishlatilsa va satrda vaqt mintaqasi ko‘rsatkichi bo‘lsa (masalan, “2026-07-21T14:30:00Z” UTC uchun Z bilan), timeZone xususiyati e’tiborga olinmaydi — formatter satrdan vaqt mintaqasini ishlatadi. Agar satrda vaqt mintaqasi bo‘lmasa, formatterning timeZone i qo‘llaniladi.
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "ru_RU")
formatter.timeZone = TimeZone(identifier: "Europe/Moscow")
formatter.dateStyle = .long
formatter.timeStyle = .short
let moscowTime = formatter.string(from: Date())
// "21 July 2026, 14:30"
// Satrda vaqt mintaqasisiz tahlil
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd HH:mm"
let utcDate = formatter.date(from: "2026-07-21 10:30")!
AutoupdatingCurrentLocale — foydalanuvchining tizim sozlamalari o‘zgarganda avtomatik yangilanadigan maxsus lokal turi. DateFormatter uni sukut bo‘yicha qo‘llab-quvvatlaydi. Agar ilova fonda ishlasa va foydalanuvchi tizim tilini o‘zgartirsa, o‘zgartirishdan oldin yaratilgan formatter eski lokaldan foydalanishda davom etadi — yangilash uchun yangi instansiya yaratish kerak.
ISO8601DateFormatter — ISO 8601 formatidagi sanalar bilan ishlash uchun ixtisoslashtirilgan formatter. Bu format REST API, JSON va ma’lumot almashinuvi uchun de-fakto standartdir. ISO8601DateFormatter DateFormatter dan ancha tez ishlaydi, chunki lokalga bog‘liq emas va qat’iy tahlil grammatikasidan foydalanadi.
Formatterning asosiy opsiyalari — .withInternetDateTime (2026-07-21T14:30:00Z), .withFractionalSeconds (millisoniyalarni qo‘shadi), .withTimeZone (vaqt mintaqasi siljishini o‘z ichiga oladi). Opsiyalarni birlashtirib istalgan ISO 8601 variantini olish mumkin: millisoniyalar bilan, vaqt mintaqasi bilan, vaqtsiz sana bilan.
JSONEncoder.DateEncodingStrategy barcha Codable modellari uchun sanalarni kodlashni global sozlash imkonini beradi. Variantlar — .iso8601 (ISO8601DateFormatter dan foydalanadi), .formatted(DateFormatter), .millisecondsSince1970, .secondsSince1970. Strategiya tanlovi serializatsiyaning butun hayot tsikliga ta’sir qiladi va barcha API endpointlari uchun yagona bo‘lishi kerak.
// ISO8601DateFormatter
let isoFormatter = ISO8601DateFormatter()
isoFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
let isoString = isoFormatter.string(from: Date())
// "2026-07-21T14:30:00.000Z"
// JSONEncoder ISO8601 bilan
let encoder = JSONEncoder()
encoder.dateEncodingStrategy = .iso8601
// Alternativ: JSONEncoder maxsus formatter bilan
let customEncoder = JSONEncoder()
customEncoder.dateEncodingStrategy = .formatted(myFormatter)
DateFormatter vs ISO8601DateFormatter — API da sanalarni serializatsiya qilish va tahlil qilish uchun ISO8601DateFormatter ni tanlang, chunki u DateFormatter dan 5-10 marta tez ishlaydi va lokalizatsiya xatolariga duch kelmaydi. DateFormatter ni foydalanuvchi interfeysi uchun qoldiring, bu erda oylar va hafta kunlari nomlari bilan lokalizatsiyalangan ko‘rinish talab qilinadi.
iOS ilovasida DateFormatter dan foydalanishning real stsenariylarini ko‘rib chiqaylik: yangiliklar ro‘yxatida ko‘rsatish, tug‘ilgan sanani kiritish va turli vaqt mintaqalarida sanalar bilan hisobot eksporti.
RelativeDateFormatter yangiliklar lentasi uchun optimaldir. U yangi yangiliklar uchun “hozir”, “5 daqiqa oldin”, “kecha” ko‘rsatadi va eskilari uchun to‘liq sanaga o‘tadi. O‘tish chegarasi calendar orqali sozlanadi: yangiliklar uchun 24 soat, messenjerlar uchun bir hafta chegarasidan foydalaning.
func formatRelativeDate(_ date: Date) -> String {
let relative = RelativeDateFormatter()
relative.unitsStyle = .full
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .short
let daysDiff = Calendar.current.dateComponents(
[.day], from: date, to: Date()
).day ?? 0
return daysDiff < 1
? relative.localizedString(for: date, relativeTo: Date())
: formatter.string(from: date)
}
Tug‘ilgan sanani kiritish — yana bir tez-tez uchraydigan stsenariy. DateFormatter aniq dateFormat “dd.MM.yyyy” va lokal “uz_UZ” bilan sozlanadi. Kiritilgan satrni tahlil qilishda mumkin bo‘lgan xatolarni boshqarish muhim: formatter noto‘g‘ri satr uchun nil qaytaradi. Muvaffaqiyatli tahlildan so‘ng sana ruxsat etilgan diapazonda ekanligi tekshiriladi — 1900 yildan oldin emas, bugundan kech emas.
Hisobotni sanalar bilan eksport qilish foydalanuvchi lokalidan mustaqil qat’iy format talab qiladi. en_US_POSIX lokali va UTC vaqt mintaqasi bilan dateFormat “yyyy-MM-dd HH:mm:ss” dan foydalaning. Bu yondashuv faylning tizimning mintaqaviy sozlamalaridan qat’iy nazar istalgan mamlakatda to‘g‘ri ochilishini kafolatlaydi.
| Stsenariy | Formatter | Asosiy sozlama |
|---|---|---|
| Yangiliklar lentasi | RelativeDateFormatter | unitsStyle = .full |
| Sana kiritish | DateFormatter | dateFormat + fallback |
| API serializatsiyasi | ISO8601DateFormatter | withInternetDateTime |
| Hisobot eksporti | DateFormatter | en_US_POSIX + UTC |
Tez-tez so‘raladigan savollar
Eng tez-tez uchraydigan sabab — dateFormat ning satr formatiga mos kelmasligi. Masalan, “dd.MM.yyyy” formati “2026-07-21” satrini tahlil qilmaydi. Ikkinchi sabab — lokal mos kelmasligi: “July 21, 2026” satri uz_UZ lokali bilan tahlil qilinmaydi. Uchinchi — LDML belgilaridagi xatolar: yyyy dan foydalaning, YYYY dan emas (farqli ma’no).
Yo‘q. DateFormatter og‘ir ob’yekt, uni ishga tushirish lokal ma’lumotlarini yuklashni o‘z ichiga oladi. Har bir formatlash turi uchun bitta instansiya yarating va uni qayta ishlating. Ko‘p ipli muhitda sinxronizatsiya uchun Thread-local storage yoki serial queue bilan formatterlar hovuzidan foydalaning.
DateFormatter mutlaq sanani (21 iyul 2026) ko‘rsatadi, RelativeDateFormatter esa nisbiy sanani (bugun, kecha, 3 kundan keyin). RelativeDateFormatter iOS 15+ da paydo bo‘lgan va xuddi shu LDML shablonidan foydalanadi, lekin avtomatik nisbiy ko‘rinishni tanlaydi.
Formatterning timeZone sini tahlildan oldin UTC ga o‘rnating. Agar server vaqt mintaqasi ko‘rsatkichisiz mahalliy vaqtda sana qaytarsa, API spetsifikatsiyasini tekshiring — katta ehtimol bilan UTC nazarda tutilgan. Oxirida Z bilan ISO 8601 uchun timeZone kerak emas — formatter siljishni satrdan tahlil qiladi.
Bitta instansiyani turli iplardan ishlatmang sinxronizatsiyasiz. Har bir ipda yangi instansiya yarating yoki saqlash uchun Thread.current.threadDictionary dan foydalaning. Alternativ — string(from:) va date(from:) vaqtida blokirovka bilan NSLock.
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.
Shuningdek o'qing