ISO8601DateFormatter হল iOS এবং macOS-এ Foundation-এর একটি ক্লাস যা আন্তর্জাতিক মান ISO 8601-এ তারিখ ফর্ম্যাটিং এবং পার্সিং-এর জন্য ডিজাইন করা হয়েছে। Apple Developer Documentation, 2024 অনুসারে, ISO8601DateFormatter ম্যানুয়ালি DateFormat সেট না করেই মিলিসেকেন্ড, টাইম জোন এবং সেকেন্ডের ভগ্নাংশ সহ ফর্ম্যাটগুলি স্বয়ংক্রিয়ভাবে হ্যান্ডেল করে। DateFormatter-এর বিপরীতে, এই ক্লাস Locale এবং TimeZone-এর উপর নির্ভরশীল নয় — এটি ISO 8601 স্পেসিফিকেশন অনুযায়ী কঠোরভাবে কাজ করে, যা এটিকে সার্ভার এবং ক্লায়েন্টের মধ্যে তারিখ আদান-প্রদানের জন্য আদর্শ করে তোলে। ক্লাসটি iOS 10 এবং macOS 10.12 থেকে উপলব্ধ।
মুখ্য বিষয়
ISO8601DateFormatter হল Foundation-এ Formatter-এর একটি বিশেষায়িত সাবক্লাস যা Date এবং ISO 8601 ফর্ম্যাট স্ট্রিং-এর মধ্যে দ্বিমুখী রূপান্তর বাস্তবায়ন করে। ISO 8601 মান (International Standard for the Representation of Dates and Times) তারিখ এবং সময় আদান-প্রদানের জন্য আন্তর্জাতিক ফর্ম্যাট নির্ধারণ করে: 2024-07-21T14:30:00+00:00। DateFormatter-এর বিপরীতে, এই ক্লাসের dateFormat নির্দিষ্ট করার প্রয়োজন নেই এবং প্রদত্ত অপশনের উপর ভিত্তি করে স্ট্রিং কাঠামো স্বয়ংক্রিয়ভাবে নির্ধারণ করে।
DateFormatter-এর তুলনায় ISO8601DateFormatter-এর প্রধান সুবিধা: লোকেলের উপর নির্ভরশীলতা নেই (পার্সিং যেকোনো ডিভাইসে একইভাবে কাজ করে), সেকেন্ডের ভগ্নাংশের জন্য বিল্ট-ইন সমর্থন (যেকোনো সংখ্যক দশমিক স্থান সহ) এবং পাস করা অপশনের উপর ভিত্তি করে স্বয়ংক্রিয় ফর্ম্যাট সনাক্তকরণ। ক্লাসটি Z-প্রত্যয় (UTC পদবি), +HH:mm ফর্ম্যাটে টাইম জোন এবং হ্রাসকৃত নির্ভুলতা (সময় ছাড়া শুধু তারিখ) সঠিকভাবে হ্যান্ডেল করে।
ISO স্পেসিফিকেশন (ISO 8601-1:2019) অনুসারে, মানটি নির্ভুলতার চারটি স্তর সমর্থন করে: বছর (2024), বছর-মাস (2024-07), পূর্ণ তারিখ (2024-07-21) এবং টাইম জোন সহ তারিখ-সময় (2024-07-21T14:30:00+00:00)। ISO8601DateFormatter ফর্ম্যাট অপশনের সংমিশ্রণের মাধ্যমে এই সমস্ত স্তর কভার করে, ডেভেলপারকে ম্যানুয়ালি dateFormat স্ট্রিং তৈরি করা থেকে মুক্ত করে।
কাজের নীতি ISO8601DateFormatter-এর বিটওয়াইজ অপশন (formatOptions) এর সংমিশ্রণের উপর ভিত্তি করে, যার প্রতিটি আউটপুটে একটি নির্দিষ্ট তারিখ বা সময় উপাদান অন্তর্ভুক্ত করে। উদাহরণস্বরূপ, .withFullDate অপশনে বছর, মাস এবং দিন অন্তর্ভুক্ত; .withTime-এ ঘন্টা, মিনিট এবং সেকেন্ড অন্তর্ভুক্ত। অপশনগুলি সংমিশ্রণ করে, ডেভেলপার dateFormat স্ট্রিং না লিখেই কাঙ্ক্ষিত নির্ভুলতা স্তর পায়।
অভ্যন্তরীণভাবে, ISO8601DateFormatter পার্সিং-এর জন্য ICU লাইব্রেরি ব্যবহার করে, কিন্তু নির্দিষ্ট ISO 8601 নিয়ম সহ। এর অর্থ হল এটি ডিভাইসের Locale এবং TimeZone সেটিংস উপেক্ষা করে — ফলাফল সর্বদা পূর্বানুমেয়। টাইম জোন সেট করতে timeZone প্রপার্টি ব্যবহার করা হয়, যা ডিফল্টরূপে UTC। timeZone nil-এ সেট করা থাকলে, ডিভাইসের স্থানীয় সময় ব্যবহার করা হয়।
| অপশন | বিবরণ | আউটপুট উদাহরণ |
|---|---|---|
| .withFullDate | বছর, মাস, দিন | 2024-07-21 |
| .withTime | ঘন্টা, মিনিট, সেকেন্ড | 14:30:00 |
| .withMilliseconds | সেকেন্ডের ভগ্নাংশ (3 অঙ্ক পর্যন্ত) | .123 |
| .withFractionalSeconds | সেকেন্ডের ভগ্নাংশ (যেকোনো নির্ভুলতা) | .123456 |
| .withTimeZone | টাইম জোন | +03:00 |
| .withColonSeparatorInTimeZone | টাইম জোনে কোলন বিভাজক | +03:00 (+0300-এর বিপরীতে) |
| .withInternetDateTime | পূর্ণ ফর্ম্যাট (তারিখ + সময় + ক্ষেত্র) | 2024-07-21T14:30:00+00:00 |
অপশন সংমিশ্রণ: .withInternetDateTime .withFullDate, .withTime এবং .withTimeZone সংমিশ্রণের সমতুল্য। মিলিসেকেন্ড সহ স্ট্রিং পার্স করতে, .withFractionalSeconds যোগ করুন। এটি মনে রাখা গুরুত্বপূর্ণ যে .withMilliseconds সেকেন্ডের ভগ্নাংশকে তিন অঙ্কে সীমাবদ্ধ করে, যখন .withFractionalSeconds যে কোনো নির্ভুলতা সমর্থন করে — দশমিক বিন্দুর পরে এক থেকে নয় অঙ্ক পর্যন্ত।
ফর্ম্যাট অপশন ISO8601DateFormatter-এর তিনটি গ্রুপে বিভক্ত: তারিখ উপাদান (withFullDate, withYear, withMonth, withDay, withWeekOfYear), সময় উপাদান (withTime, withHours, withMinutes, withSeconds) এবং অতিরিক্ত সেটিংস (withMilliseconds, withFractionalSeconds, withTimeZone, withColonSeparatorInTimeZone, withDashSeparatorInDate, withFullTime)। এগুলি সংমিশ্রণ করে, আপনি প্রায় যেকোনো ISO 8601 উপ-ফর্ম্যাট পেতে পারেন।
গুরুত্বপূর্ণ সূক্ষ্মতা: .withFractionalSeconds এবং .withMilliseconds পরস্পর বর্জনীয় — যদি উভয় সেট করা হয়, .withFractionalSeconds প্রযোজ্য হয়। সার্ভার ডেটা থেকে মিলিসেকেন্ড পার্স করার জন্য, .withFractionalSeconds সুপারিশ করা হয়, কারণ অনেক সার্ভার তিন, ছয় বা নয় অঙ্ক সহ সেকেন্ডের ভগ্নাংশ পাঠায়, এবং .withFractionalSeconds যেকোনো দৈর্ঘ্য হ্যান্ডেল করে।
import Foundation
// Configure ISO8601DateFormatter
let formatter = ISO8601DateFormatter()
formatter.timeZone = TimeZone(secondsFromGMT: 0)
// Different format option combinations
formatter.formatOptions = [.withFullDate]
let dateOnly = formatter.string(from: Date())
print("Date: \(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("Full: \(full)")
// Parse string with milliseconds
let serverString = "2024-07-21T14:30:00.123456+03:00"
if let parsed = formatter.date(from: serverString) {
print("Parsed: \(parsed)")
}
মৌলিক ব্যবহার ISO8601DateFormatter-এর একটি ইনস্ট্যান্স তৈরি, timeZone (সার্ভার ডেটার জন্য UTC সুপারিশকৃত) এবং formatOptions সেট করার মধ্যে সীমাবদ্ধ, তারপরে ফর্ম্যাটিং-এর জন্য string(from:) এবং পার্সিং-এর জন্য date(from:) কল করা যায়। DateFormatter-এর বিপরীতে, Locale নিয়ে চিন্তা করার প্রয়োজন নেই — ক্লাস আঞ্চলিক সেটিংস উপেক্ষা করে।
import Foundation
let formatter = ISO8601DateFormatter()
// Parse different ISO 8601 formats
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("Parsed '\(str)': \(autoParsed)")
} else {
// Use withFullDate for date-only strings
formatter.formatOptions = [.withFullDate]
if let fallback = formatter.date(from: str) {
print("Fallback parsed '\(str)': \(fallback)")
}
formatter.formatOptions = [.withInternetDateTime]
}
}
// Serialize to RFC 3339 (GitHub API)
formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
let rfc3339 = formatter.string(from: Date())
print("RFC 3339: \(rfc3339)")
পরিবর্তনশীল-দৈর্ঘ্যের সেকেন্ডের ভগ্নাংশ সহ তারিখ পার্স করা — অনেক আধুনিক API-র বৈশিষ্ট্য। একটি সার্ভার 2024-07-21T14:30:00.123Z (3 অঙ্ক) বা 2024-07-21T14:30:00.123456Z (6 অঙ্ক) পাঠাতে পারে। .withFractionalSeconds অপশন সহ ISO8601DateFormatter উভয় সংস্করণ সঠিকভাবে হ্যান্ডেল করবে, যখন dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ" সহ DateFormatter শুধু তিন-অঙ্কের মিলিসেকেন্ড হ্যান্ডেল করবে।
import Foundation
let variantFormatter = ISO8601DateFormatter()
variantFormatter.formatOptions = [
.withInternetDateTime,
.withFractionalSeconds
]
// Different fractional second precision
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)")
}
}
// Use withMilliseconds (3 digits only)
variantFormatter.formatOptions = [
.withInternetDateTime,
.withMilliseconds
]
let milliParsed = variantFormatter.string(from: Date())
print("With milliseconds: \(milliParsed)")
সব প্রকারের পার্সিং পরীক্ষা: দেখানো কোডটি প্রদর্শন করে যে .withFractionalSeconds সহ ISO8601DateFormatter 1 থেকে 9 অঙ্ক পর্যন্ত যেকোনো দৈর্ঘ্যের সেকেন্ডের ভগ্নাংশ সফলভাবে হ্যান্ডেল করে। এটি বিভিন্ন সার্ভার প্ল্যাটফর্মের সাথে সামঞ্জস্যের জন্য গুরুত্বপূর্ণ: .NET প্রায়ই 7 অঙ্ক (100-ন্যানোসেকেন্ড টিক) তৈরি করে, Python — 6, Java — সংস্করণের উপর নির্ভর করে 3 বা 9।
DateFormatter-ও ISO 8601 পার্স করতে পারে, কিন্তু dateFormat, locale এবং timeZone-এর ম্যানুয়াল সেটিং প্রয়োজন। মূল সমস্যা হল DateFormatter Locale-এর উপর নির্ভরশীল, এবং যদি en_US_POSIX সেট না করা হয়, তবে অ-মানক তারিখ ফর্ম্যাটযুক্ত অঞ্চলের ব্যবহারকারীদের জন্য পার্সিং ব্যর্থ হতে পারে। ISO8601DateFormatter এই সমস্যাটি আর্কিটেকচার স্তরে সমাধান করে: এটি Locale ব্যবহার করে না।
| প্যারামিটার | ISO8601DateFormatter | DateFormatter |
|---|---|---|
| Locale সেটিং | প্রয়োজন নেই (উপেক্ষা করে) | en_US_POSIX বাধ্যতামূলক |
| DateFormat | স্বয়ংক্রিয় (অপশনের মাধ্যমে) | ম্যানুয়াল ফর্ম্যাট স্ট্রিং |
| সেকেন্ডের ভগ্নাংশ | যেকোনো নির্ভুলতা (.withFractionalSeconds) | নির্দিষ্ট SSS |
| Z-প্রত্যয় | সঠিকভাবে হ্যান্ডেল করে | dateFormat-এর মাধ্যমে |
| কর্মক্ষমতা | উচ্চ (বিশেষায়িত) | নিম্ন (সাধারণ) |
| মান | শুধু ISO 8601 | যেকোনো ফর্ম্যাট |
| iOS সংস্করণ | iOS 10+ | iOS 2+ |
কখন DateFormatter ব্যবহার করবেন: যদি আপনাকে অ-ISO 8601 ফর্ম্যাটে তারিখ ফর্ম্যাট করতে হয় (যেমন UI-র জন্য "২১ জুলাই ২০২৪") অথবা যদি আপনার iOS 9 এবং পুরোনো সংস্করণের সমর্থন প্রয়োজন হয়। সার্ভার-ক্লায়েন্ট তারিখ আদান-প্রদানের সব কাজের জন্য, ISO8601DateFormatter ব্যবহার করুন — এটি নিরাপদ, বেশি কার্যকর এবং কম কোড প্রয়োজন। ISO 8601-এর জন্য DateFormatter লোকেল এবং আঞ্চলিক সেটিংস সম্পর্কিত সম্ভাব্য বাগের উৎস।
DateFormatter থেকে ISO8601DateFormatter-এ মাইগ্রেশন: DateFormatter + dateFormat + locale + timeZone তৈরিকে ISO8601DateFormatter + formatOptions + timeZone দিয়ে প্রতিস্থাপন করুন। date(from:) এর মাধ্যমে স্ট্রিং পার্সিং অপরিবর্তিত থাকে। পশ্চাদগামী সামঞ্জস্যের জন্য, আপনি DateFormatter-এ ফallback সহ #available(iOS 10, *) ব্যবহার করতে পারেন।
ভুলে যাওয়া formatOptions সেটিং ফর্ম্যাটারকে ডিফল্ট মান — .withInternetDateTime ব্যবহার করতে বাধ্য করে। যদি সার্ভার সময় ছাড়া তারিখ পাঠায় (2024-07-21), পার্সিং nil ফিরিয়ে দেবে। সর্বদা চেক করুন যে formatOptions সার্ভার থেকে আসতে পারে এমন সব সম্ভাব্য ফর্ম্যাট কভার করে। পরিবর্তনশীল ফর্ম্যাটযুক্ত API-র জন্য, বিভিন্ন অপশন সংমিশ্রণ সহ ফallback প্রচেষ্টা ব্যবহার করুন।
withMilliseconds এবং withFractionalSeconds-এর মধ্যে বিভ্রান্তি — সেকেন্ডের ভগ্নাংশ সহ তারিখ পার্স করার সময় একটি সাধারণ ভুল। withMilliseconds দশমিক বিন্দুর পরে ঠিক 3 অঙ্ক আশা করে। যদি সার্ভার 6 অঙ্ক (মাইক্রোসেকেন্ড) পাঠায়, withMilliseconds-এর সাথে পার্সিং ব্যর্থ হবে। যেকোনো সংখ্যক অঙ্কের সাথে সামঞ্জস্যের জন্য .withFractionalSeconds ব্যবহার করুন। .withFractionalSeconds iOS 13-এ উপলব্ধ হয়েছে; পুরোনো সংস্করণের জন্য, dateFormat সহ DateFormatter ব্যবহার করুন।
টাইম জোন উপেক্ষা করা — আরেকটি সাধারণ সমস্যা। যদি সার্ভার টাইম জোন (+03:00) সহ তারিখ পাঠায়, এবং ফর্ম্যাটার UTC-তে সেট করা থাকে, পার্সিং ব্যর্থ হবে না, কিন্তু ফলাফল UTC-তে হবে। ডেভেলপাররা প্রায়ই আশা করেন যে Date টাইম জোন সংরক্ষণ করবে, কিন্তু Date সময়ের একটি পরম মুহূর্ত — এটি টাইম জোন তথ্য সংরক্ষণ করে না। সঠিক প্রদর্শনের জন্য, টাইম জোন আলাদাভাবে সংরক্ষণ করুন বা সঠিক timeZone সহ ISO8601DateFormatter ব্যবহার করুন।
Apple ফোরাম (2024) অনুসারে, ISO8601DateFormatter সম্পর্কে প্রায় 20% প্রশ্ন সেই ফর্ম্যাট সম্পর্কিত যেখানে সেকেন্ড ঐচ্ছিক। ISO 8601 মান সেকেন্ড ছাড়া ফর্ম্যাট অনুমোদন করে: 2024-07-21T14:30+03:00। .withInternetDateTime সহ ISO8601DateFormatter এই ফর্ম্যাট সমর্থন করে না — এটি পার্স করতে dateFormat = "yyyy-MM-dd'T'HH:mmZ" সহ DateFormatter প্রয়োজন হবে। সংক্ষিপ্ত সময় ফর্ম্যাট ব্যবহার করে এমন API-র সাথে কাজ করার সময় এই সীমা বিবেচনা করা গুরুত্বপূর্ণ।
প্রায়শই জিজ্ঞাসিত প্রশ্ন
ISO8601DateFormatter — ISO 8601 ফর্ম্যাটে তারিখ ফর্ম্যাট এবং পার্স করার জন্য একটি বিশেষায়িত Foundation ক্লাস, যা iOS 10 থেকে উপলব্ধ। ম্যানুয়ালি dateFormat সেট না করেই স্বয়ংক্রিয়ভাবে স্ট্যান্ডার্ড ফর্ম্যাট হ্যান্ডেল করে।
ISO8601DateFormatter Locale-এর উপর নির্ভর করে না, dateFormat-এর পরিবর্তে অপশন ব্যবহার করে এবং যেকোনো দৈর্ঘ্যের সেকেন্ডের ভগ্নাংশ সঠিকভাবে হ্যান্ডেল করে। DateFormatter সার্বজনীন, কিন্তু ম্যানুয়াল সেটিং প্রয়োজন এবং আঞ্চলিক সেটিংস সম্পর্কিত বাগের জন্য প্রবণ।
.withFractionalSeconds অপশন ব্যবহার করুন — এটি দশমিক বিন্দুর পরে 1 থেকে 9 অঙ্ক সমর্থন করে। যদি নির্ভুলতা পরিবর্তিত হতে পারে তাহলে .withMilliseconds ব্যবহার করবেন না। .withFractionalSeconds iOS 13 থেকে উপলব্ধ।
ডিফল্টরূপে UTC. পরিবর্তন করতে, timeZone প্রপার্টি সেট করুন। যদি timeZone = nil হয়, ডিভাইসের স্থানীয় সময় ব্যবহার করা হয়। +HH:MM ফর্ম্যাটে স্পষ্ট টাইম জোন সহ স্ট্রিং পার্স করার সময়, ফর্ম্যাটার এটি স্বয়ংক্রিয়ভাবে বিবেচনা করে।
কারণ ডিফল্ট formatOptions = .withInternetDateTime, যা তারিখ + সময় + টাইম জোন আশা করে। শুধু তারিখ পার্স করতে, formatOptions = [.withFullDate] সেট করুন। উভয় বিকল্প সমর্থন করতে, বিভিন্ন অপশন সহ ফallback ব্যবহার করুন।
সারসংক্ষেপ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন