DateFormatter ایک Foundation کلاس ہے جو Date آبجیکٹس اور ان کی سٹرنگ نمائندگی کے درمیان دو طرفہ تبدیلی کے لیے ڈیزائن کی گئی ہے۔ یہ کلاس صارف کے لوکل، ٹائم زون اور کیلنڈر کو مدنظر رکھتی ہے، دنیا کے کسی بھی علاقے میں تاریخوں کی درست نمائش کو یقینی بناتی ہے۔ Apple Developer Documentation (2025) کے مطابق، DateFormatter چار پہلے سے طے شدہ تاریخ اور وقت کے اسٹائل کے ساتھ ساتھ ایک ٹیمپلیٹ سٹرنگ کے ذریعے مکمل طور پر حسب ضرورت فارمیٹس کو سپورٹ کرتا ہے۔ DateFormatter کے بغیر کسی بین الاقوامی ایپلیکیشن میں صارف کو صحیح طریقے سے تاریخ دکھانا ناممکن ہے۔
کلیدی نکات
DateFormatter Foundation فریم ورک کی ایک کلاس ہے جو Date اور سٹرنگ کے درمیان دو طرفہ تبدیلی کو نافذ کرتی ہے۔ یہ پہلی بار OpenStep میں NSDateFormatter کے طور پر ظاہر ہوا اور اس کے بعد سے تمام Apple پلیٹ فارمز پر تاریخ کی فارمیٹنگ کا بنیادی ٹول رہا ہے۔ یہ کلاس Formatter سے وراثت حاصل کرتی ہے اور لوکلائزڈ تاریخ ڈسپلے کے لیے ایک آسان API فراہم کرتی ہے۔
DateFormatter Unicode LDML پیٹرن کی بنیاد پر کام کرتا ہے — وہی جو ICU (International Components for Unicode) میں استعمال ہوتے ہیں۔ پیٹرن dateFormat پراپرٹی کے ذریعے سیٹ کیا جاتا ہے، جہاں علامات y, M, d, H, m, s سال، مہینہ، دن، گھنٹے، منٹ، سیکنڈ کے مساوی ہیں۔ علامت کا دہرانا فارمیٹ کا تعین کرتا ہے: «y» — دو ہندسوں والا سال، «yyyy» — چار ہندسوں والا سال۔
DateFormatter بنانا ایک مہنگا آپریشن ہے، کیونکہ ابتدا کے دوران لوکل اور کیلنڈر ڈیٹا لوڈ ہوتا ہے۔ Apple تجویز کرتا ہے کہ ہر فارمیٹنگ کی قسم کے لیے ایک بار فارمیٹر بنائیں اور اسے دوبارہ استعمال کریں۔ SwiftUI اور UIKit میں، فارمیٹرز اکثر سٹیٹک پراپرٹیز میں کیش کیے جاتے ہیں یا پہلی رسائی پر سستی سے بنائے جاتے ہیں۔
DateFormatter بہت سے iOS سسٹم اجزاء میں استعمال ہوتا ہے۔ UIDatePicker countDownTimer موڈ میں تاریخیں دکھانے کے لیے اندرونی طور پر DateFormatter استعمال کرتا ہے۔ فارمیٹر والا TextField صارف کی درج کردہ تاریخوں کو خود بخود درست کر سکتا ہے۔ Core Data Date قسم کی خصوصیات کو سپورٹ کرتا ہے، لیکن ان کی سٹرنگ نمائندگی ہمیشہ DateFormatter کے ذریعے کی جاتی ہے۔
تھریڈ سیفٹی — DateFormatter تھریڈ سیفو نہیں ہے۔ مختلف تھریڈز سے فارمیٹر کی خصوصیات میں تبدیلی غیر متعینہ رویے کا باعث بنتی ہے۔ ملٹی تھریڈڈ استعمال کے لیے، ہر تھریڈ کے لیے علیحدہ فارمیٹر انسٹینس بنائیں یا NSLock یا سیریل قطار کے ذریعے ہم آہنگی استعمال کریں۔
dateStyle اور timeStyle تاریخ ڈسپلے کو ترتیب دینے کے آسان ترین طریقے ہیں۔ ہر اسٹائل کی چار اقسام ہیں: .short, .medium, .long, .full۔ dateStyle اور timeStyle کا مجموعہ تاریخ اور وقت کے فارمیٹ کی آزادانہ ترتیب کی اجازت دیتا ہے، اور .none پراپرٹی متعلقہ حصے کو غیر فعال کر دیتی ہے۔
امریکی لوکل کے لیے، .short تاریخ کو «7/21/26» کے طور پر فارمیٹ کرتا ہے، اور روسی لوکل کے لیے «21.07.2026» کے طور پر۔ روسی لوکل کے لیے .long اسٹائل «21 جولائی 2026» آؤٹ پٹ کرتا ہے، اور .full ہفتے کے دن کے ساتھ «منگل، 21 جولائی 2026» آؤٹ پٹ کرتا ہے۔ چاروں اسٹائل خود بخود علاقائی معیارات کے مطابق ڈھل جاتے ہیں، بشمول اجزاء کی ترتیب اور جداکار۔
iOS 15+ میں SFDateFormatter RelativeDateFormatter اور DateIntervalFormatter کے ذریعے ایک متبادل طریقہ فراہم کرتا ہے۔ RelativeDateFormatter فوری سیاق و سباق کے لیے «آج»، «کل»، «3 دنوں میں» آؤٹ پٹ کرتا ہے۔ DateIntervalFormatter تاریخ کی حدود دکھاتا ہے: «21–25 جولائی 2026» — بکنگ اور منصوبہ بندی کے لیے۔
| اسٹائل | مثال (ru_RU) | مثال (en_US) |
|---|---|---|
| .short | 21.07.2026 | 7/21/26 |
| .medium | 21 جول 2026 | Jul 21, 2026 |
| .long | 21 جولائی 2026 | July 21, 2026 |
| .full | منگل، 21 جولائی 2026 | Tuesday, July 21, 2026 |
اسٹائل کو یکجا کرتے وقت، DateFormatter خود بخود جداکار کا انتخاب کرتا ہے: .short.date + .short.time کے لیے نتیجہ «21.07.2026, 14:30» ہو سکتا ہے۔ .full.date + .full.time کے لیے — «منگل، 21 جولائی 2026, 14:30:00 MSK»۔ جداکار لوکل کے ذریعے منظم کیا جاتا ہے، ڈویلپر کے ذریعے نہیں — یہ صارف کی علاقائی توقعات کے مطابقت کو یقینی بناتا ہے۔
dateFormat Unicode LDML تصریحی علامات کا استعمال کرتے ہوئے ایک صوابدیدی فارمیٹنگ پیٹرن سیٹ کرنے کی اجازت دیتا ہے۔ یہ ڈسپلے پر مکمل کنٹرول دیتا ہے: آپ صرف سال اور مہینہ دکھا سکتے ہیں، یا تاریخ کے بغیر ہفتے کا دن، یا سیکنڈ کے بغیر وقت۔ حسب ضرورت فارمیٹ مخصوص ڈیزائن کی ضروریات کے لیے ناگزیر ہے۔
بنیادی علامات — yyyy (سال: 2026)، MM (مہینہ: 07)، dd (دن: 21)، HH (گھنٹے: 14)، mm (منٹ: 30)، ss (سیکنڈ: 00)۔ پورے مہینے کے نام کے لیے MMMM (جولائی) استعمال کریں، مختصر کے لیے — MMM (جول)۔ ہفتے کا دن — EEEE (منگل)، مختصر — E (منگل)۔
dateFormat استعمال کرتے وقت فارمیٹر کا لوکل سیٹ کرنا ضروری ہے۔ اگر لوکل سیٹ نہیں ہے تو، فارمیٹر سسٹم لوکل استعمال کرتا ہے، جو API میں ایک مقررہ فارمیٹ کے لیے ناپسندیدہ ہو سکتا ہے۔ Apple ایک مقررہ بین العلاقائی فارمیٹ کے لیے locale = Locale(identifier: «en_US_POSIX») سیٹ کرنے کی سفارش کرتا ہے، خاص طور پر سرور کے جوابات سے تاریخیں پارس کرتے وقت۔
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "ru_RU")
formatter.dateFormat = "d MMMM yyyy"
let customString = formatter.string(from: Date())
// "21 July 2026"
// حسب ضرورت سٹرنگ پارس کرنا
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let date = formatter.date(from: "2026-07-21 14:30:00")!
dateFormat میں غلطی ایپلیکیشن کریش کی عام وجوہات میں سے ایک ہے۔ اگر فارمیٹ سٹرنگ سے مطابقت نہیں رکھتا تو، date(from:) طریقہ nil لوٹاتا ہے۔ محفوظ آپشنل انریپنگ کے لیے guard let یا ?? استعمال کریں۔ فارمیٹ کی توثیق کرنے کے لیے، اسے تمام معاون زبانوں پر آزمائیں — کچھ LDML علامات مختلف لوکلز میں مختلف کام کرتی ہیں۔
Locale اس بات کا تعین کرتا ہے کہ مہینوں کے نام، ہفتے کے دنوں کے نام اور جداکار کیسے دکھائے جاتے ہیں۔ DateFormatter بطور ڈیفالٹ Locale.current استعمال کرتا ہے، لیکن کچھ منظرناموں میں ایک مخصوص لوکل بتانے کی ضرورت ہوتی ہے: لاگز میں مقررہ فارمیٹ کے لیے en_US_POSIX استعمال کریں، سرور کی تاریخوں کے لیے — سرور سے مماثل لوکل۔
TimeZone پراپرٹی ڈسپلے کے لیے ٹائم زون کا تعین کرتی ہے۔ بطور ڈیفالٹ سسٹم ٹائم زون استعمال ہوتا ہے، لیکن بین الاقوامی سامعین والی ایپلیکیشنز کے لیے اکثر صارف کے ٹائم زون یا UTC میں تاریخیں دکھانے کی ضرورت ہوتی ہے۔ timeZone تبدیل کرنا صرف ڈسپلے کو متاثر کرتا ہے — Date کی قیمت تبدیل نہیں ہوتی۔
ایک اہم خصوصیت: اگر DateFormatter کسی سٹرنگ کو پارس کرنے کے لیے استعمال کیا جاتا ہے اور سٹرنگ میں ٹائم زون کا اشارہ ہوتا ہے (مثال کے طور پر، UTC کے لیے Z کے ساتھ «2026-07-21T14:30:00Z»)، timeZone پراپرٹی کو نظر انداز کیا جاتا ہے — فارمیٹر سٹرنگ سے ٹائم زون استعمال کرتا ہے۔ اگر سٹرنگ میں ٹائم زون موجود نہیں ہے تو، فارمیٹر کا timeZone لاگو ہوتا ہے۔
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"
// سٹرنگ میں ٹائم زون کے بغیر پارس کرنا
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd HH:mm"
let utcDate = formatter.date(from: "2026-07-21 10:30")!
AutoupdatingCurrentLocale — ایک خاص لوکل کی قسم ہے جو صارف کی سسٹم سیٹنگز تبدیل ہونے پر خود بخود اپ ڈیٹ ہو جاتی ہے۔ DateFormatter بطور ڈیفالٹ اسے سپورٹ کرتا ہے۔ اگر ایپلیکیشن پس منظر میں چل رہی ہے اور صارف سسٹم کی زبان تبدیل کرتا ہے، تو تبدیلی سے پہلے بنایا گیا فارمیٹر پرانے لوکل کا استعمال جاری رکھے گا — اپ ڈیٹ کرنے کے لیے ایک نیا انسٹینس بنانے کی ضرورت ہے۔
ISO8601DateFormatter ISO 8601 فارمیٹ میں تاریخوں کے ساتھ کام کرنے کے لیے ایک خصوصی فارمیٹر ہے۔ یہ فارمیٹ REST API، JSON اور ڈیٹا کے تبادلے کے لیے حقیقی معیار ہے۔ ISO8601DateFormatter DateFormatter کے مقابلے میں نمایاں طور پر تیز کام کرتا ہے کیونکہ یہ لوکل پر منحصر نہیں ہوتا اور ایک مقررہ پارسنگ گرامر استعمال کرتا ہے۔
فارمیٹر کے اہم اختیارات — .withInternetDateTime (2026-07-21T14:30:00Z)، .withFractionalSeconds (ملی سیکنڈز شامل کرتا ہے)، .withTimeZone (ٹائم زون آفسیٹ شامل کرتا ہے)۔ اختیارات کو ملا کر آپ کوئی بھی ISO 8601 ویرینٹ حاصل کر سکتے ہیں: ملی سیکنڈز کے ساتھ، ٹائم زون کے ساتھ، صرف تاریخ کے ساتھ۔
JSONEncoder.DateEncodingStrategy تمام Codable ماڈلز کے لیے عالمی طور پر تاریخ انکوڈنگ کو ترتیب دینے کی اجازت دیتا ہے۔ اختیارات — .iso8601 (ISO8601DateFormatter استعمال کرتا ہے)، .formatted(DateFormatter)، .millisecondsSince1970، .secondsSince1970۔ حکمت عملی کا انتخاب پورے سیریلائزیشن لائف سائیکل کو متاثر کرتا ہے اور تمام API اینڈ پوائنٹس پر یکساں ہونا چاہیے۔
// ISO8601DateFormatter
let isoFormatter = ISO8601DateFormatter()
isoFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
let isoString = isoFormatter.string(from: Date())
// "2026-07-21T14:30:00.000Z"
// ISO8601 کے ساتھ JSONEncoder
let encoder = JSONEncoder()
encoder.dateEncodingStrategy = .iso8601
// متبادل: حسب ضرورت فارمیٹر کے ساتھ JSONEncoder
let customEncoder = JSONEncoder()
customEncoder.dateEncodingStrategy = .formatted(myFormatter)
DateFormatter بمقابلہ ISO8601DateFormatter — API میں تاریخوں کو سیریلائز اور پارس کرنے کے لیے ISO8601DateFormatter کا انتخاب کریں، کیونکہ یہ DateFormatter سے 5-10 گنا تیز ہے اور لوکلائزیشن کی غلطیوں کا شکار نہیں ہے۔ DateFormatter کو یوزر انٹرفیس کے لیے چھوڑ دیں جہاں صارف کی مادری زبان میں مہینوں اور دنوں کے ناموں کے ساتھ لوکلائزڈ ڈسپلے کی ضرورت ہوتی ہے۔
آئیے iOS ایپلیکیشن میں DateFormatter کے استعمال کے حقیقی منظرناموں پر نظر ڈالتے ہیں: نیوز فیڈ میں تاریخیں دکھانا، تاریخ پیدائش درج کرنا اور مختلف ٹائم زونز میں تاریخوں کے ساتھ رپورٹ برآمد کرنا۔
RelativeDateFormatter نیوز فیڈز کے لیے بہترین ہے۔ یہ تازہ خبروں کے لیے «ابھی»، «5 منٹ پہلے»، «کل» دکھاتا ہے اور پرانی خبروں کے لیے مکمل تاریخ پر سوئچ کرتا ہے۔ سوئچ کی حد کیلنڈر کے ذریعے ترتیب دی جاتی ہے: خبروں کے لیے 24 گھنٹے کی حد استعمال کریں، میسنجر کے لیے — ایک ہفتہ۔
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)
}
تاریخ پیدائش درج کرنا — ایک اور عام منظرنامہ۔ DateFormatter ایک مخصوص dateFormat «dd.MM.yyyy» اور locale «ru_RU» کے ساتھ ترتیب دیا جاتا ہے۔ درج کردہ سٹرنگ کو پارس کرتے وقت ممکنہ غلطیوں کو سنبھالنا ضروری ہے: فارمیٹر غلط سٹرنگ کے لیے nil لوٹاتا ہے۔ کامیاب پارسنگ کے بعد، تاریخ کو قابل قبول حد میں جانچا جاتا ہے — 1900 سے پہلے نہیں، آج کے بعد نہیں۔
تاریخوں کے ساتھ رپورٹ برآمد کرنا کے لیے صارف کے لوکل سے آزاد ایک مقررہ فارمیٹ کی ضرورت ہوتی ہے۔ locale en_US_POSIX اور ٹائم زون UTC کے ساتھ dateFormat «yyyy-MM-dd HH:mm:ss» استعمال کریں۔ یہ طریقہ اس بات کی ضمانت دیتا ہے کہ فائل سسٹم کی علاقائی سیٹنگز سے قطع نظر کسی بھی ملک میں صحیح طور پر کھلے گی۔
| منظرنامہ | فارمیٹر | اہم ترتیب |
|---|---|---|
| نیوز فیڈ | RelativeDateFormatter | unitsStyle = .full |
| تاریخ داخلہ | DateFormatter | dateFormat + فال بیک |
| API سیریلائزیشن | ISO8601DateFormatter | withInternetDateTime |
| رپورٹ برآمد | DateFormatter | en_US_POSIX + UTC |
اکثر پوچھے گئے سوالات
سب سے عام وجہ — dateFormat اور سٹرنگ فارمیٹ کے درمیان مماثلت نہ ہونا۔ مثال کے طور پر، فارمیٹ «dd.MM.yyyy» سٹرنگ «2026-07-21» کو پارس نہیں کرے گا۔ دوسری وجہ — لوکل کی مماثلت نہ ہونا: سٹرنگ «July 21, 2026» ru_RU لوکل کے ساتھ پارس نہیں ہوگی۔ تیسری — LDML علامات میں ٹائپو: yyyy استعمال کریں، YYYY نہیں (مختلف معنی)۔
نہیں۔ DateFormatter ایک بھاری آبجیکٹ ہے، اس کی ابتدا میں لوکل ڈیٹا لوڈ کرنا شامل ہے۔ ہر فارمیٹنگ کی قسم کے لیے ایک انسٹینس بنائیں اور اسے دوبارہ استعمال کریں۔ ملٹی تھریڈڈ ماحول میں، تھریڈ لوکل سٹوریج یا ہم آہنگی کے لیے سیریل قطار کے ساتھ فارمیٹر پول استعمال کریں۔
DateFormatter ایک مطلق تاریخ دکھاتا ہے (21 جولائی 2026)، جبکہ RelativeDateFormatter ایک نسبتی تاریخ دکھاتا ہے (آج، کل، 3 دنوں میں)۔ RelativeDateFormatter iOS 15+ میں متعارف کرایا گیا تھا اور یہی LDML ٹیمپلیٹ استعمال کرتا ہے لیکن خود بخود نسبتی ڈسپلے کا انتخاب کرتا ہے۔
فارمیٹر کا timeZone پارس کرنے سے پہلے UTC پر سیٹ کریں۔ اگر سرور ٹائم زون کے اشارے کے بغیر مقامی وقت میں تاریخ لوٹاتا ہے تو، API کی تفصیلات چیک کریں — غالباً UTC مراد ہے۔ آخر میں Z کے ساتھ ISO 8601 کے لیے، timeZone کی ضرورت نہیں ہے — فارمیٹر سٹرنگ سے آفسیٹ پارس کرتا ہے۔
ہم آہنگی کے بغیر مختلف تھریڈز سے ایک انسٹینس استعمال نہ کریں۔ ہر تھریڈ میں ایک نیا انسٹینس بنائیں یا سٹوریج کے لیے Thread.current.threadDictionary استعمال کریں۔ ایک متبادل string(from:) اور date(from:) کی مدت کے لیے لاکنگ کے ساتھ NSLock ہے۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں