Locale হল iOS এবং macOS-এ একটি Foundation ক্লাস যা ব্যবহারকারীর ভাষাগত এবং সাংস্কৃতিক রীতিনীতিগুলিকে ধারণ করে: তারিখের বিন্যাস, সংখ্যার বিন্যাস, মুদ্রা এবং পরিমাপের একক। Apple Developer Documentation, 2024 অনুসারে, Locale নির্ধারণ করে কীভাবে DateFormatter একটি মাস প্রদর্শন করে (জানুয়ারি বা January), একটি সংখ্যায় দশমিক বিভাজক (কমা বা বিন্দু) এবং মুদ্রা প্রতীক (রুবেল, ডলার বা ইউরো)। প্রতিটি Locale ইনস্ট্যান্স ru_RU বা en_US-এর মতো একটি শনাক্তকারীর সাথে সংযুক্ত, যেখানে প্রথম অংশটি ভাষা কোড (ISO 639-1) এবং দ্বিতীয়টি অঞ্চল কোড (ISO 3166-1)। TimeZone-এর বিপরীতে, Locale সময়ের পরম মানকে প্রভাবিত করে না, শুধুমাত্র এর স্ট্রিং উপস্থাপনাকে প্রভাবিত করে।
মূল পয়েন্ট
Locale হল Swift-এ একটি ভ্যালু টাইপ (Objective-C-তে NSLocale) যা একটি নির্দিষ্ট ভাষা এবং অঞ্চলের জন্য নির্দিষ্ট ফর্ম্যাটিং নিয়মের একটি সেট উপস্থাপন করে। TimeZone-এর বিপরীতে, যা সময়ের পরম অফসেট নির্ধারণ করে, Locale নির্ধারণ করে যে সময়, সংখ্যা এবং মুদ্রা স্ট্রিং উপস্থাপনায় কেমন দেখায়। একই তারিখ 2024-07-21 ru_RU-এর জন্য “21 জুলাই 2024” এবং en_US-এর জন্য “July 21, 2024” হিসাবে প্রদর্শিত হবে।
প্রতিটি Locale ইনস্ট্যান্সে দুটি উপাদান থাকে: ভাষা (মাসের নাম, সপ্তাহের দিন, শব্দের ক্রম নির্ধারণ করে) এবং অঞ্চল (সংখ্যা বিন্যাস, মুদ্রা, ক্যালেন্ডার নির্ধারণ করে)। এই উপাদানগুলির সংমিশ্রণ BCP 47 মান অনুযায়ী একটি শনাক্তকারীতে এনকোড করা হয়: ru_RU (রুশ ভাষা, রাশিয়া), en_US (ইংরেজি, মার্কিন যুক্তরাষ্ট্র), de_DE (জার্মান, জার্মানি)।
Unicode CLDR (2024) অনুসারে, iOS-এ সমর্থিত লোকেলের সংখ্যা 700-এর বেশি ভাষা-অঞ্চল সংমিশ্রণ অতিক্রম করে। Foundation CLDR (Common Locale Data Repository) থেকে ডেটা ব্যবহার করে — এটি ইউনিকোড কনসোর্টিয়াম দ্বারা রক্ষণাবেক্ষিত স্থানীয়করণ ডেটার সবচেয়ে ব্যাপক ভান্ডার। এটি সমস্ত Apple ডিভাইস জুড়ে সামঞ্জস্যপূর্ণ ফর্ম্যাটিং নিশ্চিত করে।
DateFormatter সঠিক মাস এবং দিনের নাম নির্বাচন করতে, তারিখের উপাদানগুলির ক্রম (দিন/মাস/বছর বা মাস/দিন/বছর) এবং বিভাজক নির্ধারণ করতে Locale ব্যবহার করে। স্পষ্টভাবে Locale নির্দিষ্ট না করে, DateFormatter ডিভাইস লোকেল ব্যবহার করে — এটি UI-এর জন্য সঠিক কিন্তু সার্ভার ডেটার জন্য বিপজ্জনক যেখানে বিন্যাস স্থির হওয়া উচিত।
| উপাদান | ru_RU | en_US | de_DE |
|---|---|---|---|
| তারিখ (medium) | 21 জুলাই 2024 | Jul 21, 2024 | 21.07.2024 |
| সংখ্যা (1000.5) | 1 000,5 | 1,000.5 | 1.000,5 |
| মুদ্রা (100) | 100,00 ₽ | $100.00 | 100,00 € |
| ক্যালেন্ডার | গ্রেগরিয়ান | গ্রেগরিয়ান | গ্রেগরিয়ান |
| তালিকা বিভাজক | ; | , | ; |
NumberFormatter দশমিক বিভাজক (কমা বা বিন্দু), গ্রুপিং বিভাজক (স্পেস, কমা, বিন্দু) এবং মুদ্রা প্রতীক নির্ধারণ করতে Locale ব্যবহার করে। সংখ্যা পার্স করার সময় Locale উপেক্ষা করা আন্তর্জাতিক অ্যাপ্লিকেশনে বাগের সাধারণ কারণগুলির মধ্যে একটি: সংখ্যা “1,5”-এর অর্থ ru_RU-এর জন্য “সাড়ে এক”, কিন্তু en_US-এর জন্য ডিজিটাল পার্সার এটি কমার পরে “পাঁচ” হিসাবে পড়বে।
গুরুত্বপূর্ণ: Calendar.current-এর মাধ্যমে তৈরি Calendar ডিভাইস লোকেল উত্তরাধিকার সূত্রে পায়। স্পষ্টভাবে নির্ধারিত লোকেল সহ Calendar(identifier: .gregorian) ভবিষ্যদ্বাণীযোগ্য ফর্ম্যাটিংয়ের জন্য প্রস্তাবিত পদ্ধতি। ISO 8601 তারিখ নিয়ে কাজ করার সময়, সর্বদা Locale(identifier: “en_US_POSIX”) ব্যবহার করুন — প্রযুক্তিগত ফর্ম্যাটিংয়ের জন্য একটি বিশেষ লোকেল যা আঞ্চলিক সেটিংস দ্বারা প্রভাবিত হয় না।
Locale শনাক্তকারী একটি ভাষা কোড (ISO 639-1, দুটি অক্ষর) এবং একটি অঞ্চল কোড (ISO 3166-1, দুটি অক্ষর) নিয়ে গঠিত, যা আন্ডারস্কোর দ্বারা পৃথক করা হয়। উদাহরণ: ru_RU, en_US, fr_FR, zh_Hans_CN (চীনা, সরলীকৃত লিপি, চীন)। Foundation BCP 47 বিন্যাসে শনাক্তকারীও সমর্থন করে: ru-RU, en-US, ওয়েব স্ট্যান্ডার্ডে ব্যবহৃত।
সম্পূর্ণ শনাক্তকারী ছাড়াও, Locale শুধুমাত্র ভাষা দ্বারা তৈরি করা যেতে পারে: Locale(identifier: “ru”) রুশ ভাষা এবং সেই ভাষার জন্য ডিফল্ট অঞ্চল (সাধারণত রাশিয়া) সহ একটি লোকেল ফেরত দেয়। একইভাবে ইংরেজির জন্য: Locale(identifier: “en”) মার্কিন অঞ্চল ব্যবহার করে। এই পদ্ধতিটি একটি নির্দিষ্ট অঞ্চলের সাথে বাঁধা ছাড়াই ফর্ম্যাটিং ভাষা সেট করার জন্য দরকারী।
বিশেষ লোকেল এর মধ্যে en_US_POSIX অন্তর্ভুক্ত — তারিখ এবং সংখ্যার মেশিন ফর্ম্যাটিংয়ের জন্য একটি প্রযুক্তিগত লোকেল, যা ব্যবহারকারীর সেটিংস নির্বিশেষে একটি স্থিতিশীল বিন্যাস নিশ্চিত করে। এই লোকেলটি সার্ভার API থেকে তারিখ পার্স করার জন্য বাধ্যতামূলক, বিশেষ করে ISO 8601 বিন্যাসের জন্য। এটি গ্রেগরিয়ান ক্যালেন্ডার, 24-ঘন্টা সময় বিন্যাস এবং দশমিক বিভাজক হিসাবে বিন্দু ব্যবহার করে।
import Foundation
// উপলব্ধ লোকেল শনাক্তকারী
let available: [String] = Locale.availableIdentifiers
print("মোট লোকেল: \(available.count)")
// রুশ লোকেল ফিল্টার করুন
let russianLocales = available.filter { $0.hasPrefix("ru") }
print("রুশ লোকেল: \(russianLocales)")
// লোকেল উপাদান
let locale = Locale(identifier: "de_DE")
print("ভাষা: \(locale.languageCode ?? "nil")")
print("অঞ্চল: \(locale.regionCode ?? "nil")")
print("মুদ্রা: \(locale.currencyCode ?? "nil")")
print("ক্যালেন্ডার: \(locale.calendar.identifier)")
উপলব্ধ লোকেল পরীক্ষা Locale.availableIdentifiers-এর মাধ্যমে বর্তমান iOS সংস্করণ দ্বারা সমর্থিত সমস্ত শনাক্তকারীর একটি অ্যারে ফেরত দেয়। অঞ্চল অনুসারে ফিল্টার করতে, regionCode পরীক্ষা সহ Locale.availableIdentifiers.filter ব্যবহার করুন। এটি হার্ডকোডেড তালিকা ছাড়া অঞ্চল নির্বাচন UI তৈরি করার জন্য দরকারী।
Locale.current হল iOS সেটিংসে (Settings > General > Language & Region) ব্যবহারকারীর দ্বারা নির্ধারিত ডিভাইসের বর্তমান লোকেল পাওয়ার প্রাথমিক উপায়। অ্যাপ্লিকেশন পুনরায় চালু না করেই সেটিংসে ভাষা বা অঞ্চল পরিবর্তন করার সময় এই বৈশিষ্ট্যটি স্বয়ংক্রিয়ভাবে আপডেট হয়। তবে, এটি সামগ্রী প্রদর্শনের জন্য পছন্দের লোকেলের সাথে মেলে না: একজন ব্যবহারকারী ইন্টারফেস ভাষা ইংরেজিতে সেট করতে পারেন কিন্তু রুশ বিন্যাসে তারিখ দেখতে পারেন।
ব্যবহারকারীর পছন্দের আরও সঠিক নির্ধারণের জন্য, Locale.preferredLanguages ব্যবহার করুন — ব্যবহারকারীর অগ্রাধিকার অনুসারে ভাষার একটি অ্যারে। প্রথম উপাদানটি প্রাথমিক ইন্টারফেস ভাষা। এই তালিকাটি Language & Region-এর সেটিংসের সাথে মিলে যায়, যার মধ্যে পছন্দের ক্রমে ভাষাগুলি টেনে আনা অন্তর্ভুক্ত। যোগাযোগ অ্যাপ্লিকেশনগুলি (মেসেঞ্জার, ইমেল ক্লায়েন্ট) সামগ্রী প্রদর্শনের ভাষা নির্বাচন করার সময় এই ক্রমটি বিবেচনা করা উচিত।
import Foundation
// বর্তমান সিস্টেম লোকেল
let current = Locale.current
print("বর্তমান লোকেল: \(current.identifier)")
print("ভাষা: \(current.language?.disjointName ?? "nil")")
// ব্যবহারকারীর পছন্দের ভাষা
let preferred = Locale.preferredLanguages
print("পছন্দের ভাষা: \(preferred)")
// বর্তমান লোকেল থেকে অঞ্চল পান
if let region = current.regionCode {
let regionLocale = Locale(identifier: "en_\(region)")
let countryName = regionLocale.localizedString(
forRegionCode: region
)
print("দেশ: \(countryName ?? region)")
}
// 24 ঘন্টা বিন্যাস পরীক্ষা করুন
let uses24h = current.uses24hClock(
for: .dateAndTime
)
print("24 ঘন্টা ব্যবহার করে: \(uses24h)")
UI-তে স্থানীয়করণ: ইন্টারফেস ভাষায় মাস এবং দিনের নাম প্রদর্শন করতে, নির্ধারিত লোকেল সহ Calendar ব্যবহার করুন। Calendar.current.symbols(for: .month) বর্তমান লোকেলের ভাষায় মাসের নাম ফেরত দেয়। ব্যবহারকারীর ভাষায় দেশের নাম প্রদর্শন করতে, Locale.current.localizedString(forRegionCode:) ব্যবহার করুন।
তারিখ ফর্ম্যাটিং লোকেল সচেতনতার সাথে ব্যবহারকারীকে তারিখ প্রদর্শন করার সময় একটি মূল কাজ। নির্ধারিত লোকেল সহ DateFormatter স্বয়ংক্রিয়ভাবে ব্যবহারকারীর অঞ্চলের জন্য সঠিক তারিখ এবং সময় বিন্যাস নির্বাচন করে। .short, .medium, .long, .full মান সহ dateStyle এবং timeStyle-এর জন্য, ফর্ম্যাটার তারিখের উপাদানগুলি গঠনের জন্য লোকেল নিয়ম ব্যবহার করে।
import Foundation
let date = Date()
// বিভিন্ন লোকেলের সাথে বিন্যাস
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.locale = Locale(identifier: "ru_RU")
print("রুশ: \(formatter.string(from: date))")
formatter.locale = Locale(identifier: "en_US")
print("ইংরেজি: \(formatter.string(from: date))")
formatter.locale = Locale(identifier: "ja_JP")
print("জাপানি: \(formatter.string(from: date))")
// লোকেলের সাথে মুদ্রা ফর্ম্যাটিং
let numFormatter = NumberFormatter()
numFormatter.numberStyle = .currency
numFormatter.locale = Locale(identifier: "de_DE")
print("জার্মান মুদ্রা: \(numFormatter.string(from: 1234.56) ?? "nil")")
numFormatter.locale = Locale(identifier: "en_US")
print("মার্কিন মুদ্রা: \(numFormatter.string(from: 1234.56) ?? "nil")")
সার্ভার API থেকে তারিখ পার্স করা নির্দিষ্ট বিন্যাসের জন্য সর্বদা Locale(identifier: “en_US_POSIX”) ব্যবহার করা উচিত। সার্ভারগুলি সাধারণত ইংরেজি মাসের নাম সহ ISO 8601 বিন্যাসে তারিখ পাঠায়, এবং বর্তমান ডিভাইস লোকেল ব্যবহার করলে পার্সিং ত্রুটি হতে পারে যদি ব্যবহারকারী অ-ইংরেজি অঞ্চলে থাকে। en_US_POSIX নিশ্চিত করে যে পার্সিং ডিভাইস সেটিংসের উপর নির্ভর করে না।
import Foundation
// সঠিক সার্ভার তারিখ পার্সিং
let isoFormatter = DateFormatter()
isoFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
isoFormatter.locale = Locale(identifier: "en_US_POSIX")
isoFormatter.timeZone = TimeZone(secondsFromGMT: 0)
let serverDate = "2024-07-21T14:30:00+0000"
if let parsed = isoFormatter.date(from: serverDate) {
print("পার্স করা তারিখ: \(parsed)")
}
// স্থানীয়কৃত মুদ্রার নাম
let usLocale = Locale(identifier: "en_US")
let currencyName = usLocale.localizedString(
forCurrencyCode: "RUB"
)
print("মার্কিন লোকেলে রুশ রুবেল: \(currencyName ?? "nil")")
অতিরিক্ত ক্ষমতা: Locale তার উপাদানগুলির স্থানীয়কৃত বিবরণ প্রদান করে methods localizedString(forRegionCode:), localizedString(forLanguageCode:), localizedString(forCurrencyCode:) এবং localizedString(forCalendarIdentifier:) এর মাধ্যমে। এই পদ্ধতিগুলি যে লোকেলে কল করা হয় তার ভাষায় নাম ফেরত দেয়। উদাহরণস্বরূপ, Locale(identifier: “ru_RU”).localizedString(forCountryCode: “DE”) “জার্মানি” ফেরত দেয়।
সংখ্যা পার্স করার সময় Locale উপেক্ষা করা আন্তর্জাতিক অ্যাপ্লিকেশনে একটি গুরুতর ত্রুটি। স্পষ্ট লোকেল ছাড়া NumberFormatter বর্তমান ডিভাইস লোকেল ব্যবহার করে। যদি রাশিয়ার কোনো ব্যবহারকারী “1,5” প্রবেশ করে, NumberFormatter.number(from: “1,5”) সঠিকভাবে 1.5 ফেরত দেয়। কিন্তু একই কোড en_US লোকেল সহ একটি ডিভাইসে চালালে, পার্সিং nil ফেরত দেয় কারণ en_US-এর জন্য দশমিক বিভাজক হল বিন্দু।
সার্ভার তারিখের জন্য en_US_POSIX-এর অনুপস্থিতি সূক্ষ্ম বাগের দিকে নিয়ে যায়। dateFormat এবং locale = Locale.current সহ DateFormatter যেসব অঞ্চলের ব্যবহারকারীদের জন্য ভেঙে যেতে পারে যেখানে তারিখের বিন্যাস আমেরিকান থেকে আলাদা। উদাহরণস্বরূপ, জার্মানিতে DateFormatter “21.07.2024” আশা করতে পারে যখন সার্ভার “07/21/2024” পাঠায়। en_US_POSIX ব্যবহারকারীর অঞ্চল নির্বিশেষে মেশিন পার্সিংয়ের জন্য একটি নির্দিষ্ট বিন্যাস নিশ্চিত করে।
Date ব্যবহার করার পরিবর্তে তারিখের স্ট্রিং তুলনা করা আরেকটি সাধারণ ভুল। ডেভেলপাররা কখনও কখনও বিভিন্ন লোকেল থেকে তারিখের স্ট্রিং উপস্থাপনা তুলনা করে, ভুল ফলাফল পায়। Locale শুধুমাত্র প্রদর্শন পরিবর্তন করে, তারিখের পরম মান নয়। সর্বদা Date অবজেক্টের তুলনা করুন, তাদের স্ট্রিং উপস্থাপনা নয়। তারিখের উপাদান তুলনা করার জন্য, স্পষ্টভাবে নির্ধারিত লোকেল সহ Calendar ব্যবহার করুন।
WWDC 2023 অনুসারে, অ্যাপ্লিকেশনগুলিতে প্রায় 30% আন্তর্জাতিকীকরণ সমস্যা ভুল Locale কনফিগারেশনের সাথে সম্পর্কিত। Apple সার্ভার ডেটা নিয়ে কাজ করার সময় সর্বদা DateFormatter এবং NumberFormatter-এর জন্য স্পষ্টভাবে লোকেল সেট করার এবং শুধুমাত্র UI প্রদর্শনের জন্য Locale.current ব্যবহার করার পরামর্শ দেয়। এই সহজ অভ্যাসটি আঞ্চলিক সেটিংস সম্পর্কিত বেশিরভাগ বাগ দূর করে।
সচরাচর জিজ্ঞাসিত প্রশ্ন
Locale একটি Foundation ক্লাস যা সাংস্কৃতিক এবং ভাষাগত ফর্ম্যাটিং নিয়ম উপস্থাপন করে: তারিখ বিন্যাস, সংখ্যা বিন্যাস, মুদ্রা এবং পরিমাপের একক। এটি স্থানীয়কৃত ডেটা প্রদর্শনের জন্য DateFormatter, NumberFormatter এবং Calendar-এর সাথে একসাথে ব্যবহৃত হয়।
Locale প্রদর্শন বিন্যাস (ভাষা, আঞ্চলিক রীতিনীতি) নির্ধারণ করে, যখন TimeZone UTC-এর সাপেক্ষে সময়ের পরম অফসেট নির্ধারণ করে। Locale স্ট্রিং উপস্থাপনাকে প্রভাবিত করে, TimeZone সময়ের সংখ্যাগত মানকে প্রভাবিত করে। সম্পূর্ণ তারিখ ফর্ম্যাটিংয়ের জন্য উভয়ই একসাথে ব্যবহৃত হয়।
en_US_POSIX প্রযুক্তিগত ফর্ম্যাটিংয়ের জন্য একটি বিশেষ লোকেল যা ব্যবহারকারীর সেটিংস নির্বিশেষে একটি স্থিতিশীল বিন্যাস নিশ্চিত করে। সার্ভার তারিখ (ISO 8601) পার্স করার জন্য এবং API-এর সাথে কাজ করার জন্য বাধ্যতামূলক যেখানে বিন্যাস ভবিষ্যদ্বাণীযোগ্য হতে হবে।
Locale.availableIdentifiers সমস্ত সমর্থিত লোকেলের শনাক্তকারী সহ স্ট্রিংগুলির একটি অ্যারে ফেরত দেয়। ভাষা অনুসারে ফিল্টার করতে, hasPrefix সহ filter ব্যবহার করুন; অঞ্চল পেতে, Locale(identifier:).regionCode ব্যবহার করুন।
NumberFormatter দশমিক বিভাজক (কমা বা বিন্দু), মুদ্রা প্রতীক এবং গ্রুপিং বিভাজক নির্ধারণ করতে Locale ব্যবহার করে। নির্দিষ্ট বিন্যাসের জন্য, লোকেল en_US_POSIX-এ সেট করুন বা ফর্ম্যাটার বৈশিষ্ট্যগুলি স্পষ্টভাবে সেট করুন।
সারসংক্ষেপ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন