Locale — adalah kelas Foundation di iOS dan macOS yang merangkum konvensi linguistik dan budaya pengguna: format tanggal, angka, mata uang, dan satuan ukuran. Menurut Apple Developer Documentation, 2024, Locale menentukan bagaimana DateFormatter menampilkan bulan (Januari atau January), pemisah desimal dalam angka (koma atau titik), dan simbol mata uang (rupiah, dolar, atau euro). Setiap instance Locale terikat pada pengenal seperti ru_RU atau en_US, di mana bagian pertama adalah kode bahasa (ISO 639-1) dan bagian kedua adalah kode wilayah (ISO 3166-1). Tidak seperti TimeZone, Locale tidak memengaruhi nilai absolut waktu, hanya representasi stringnya.
Poin Utama
Locale — adalah value-type di Swift (NSLocale di Objective-C) yang mewakili seperangkat aturan format yang khas untuk bahasa dan wilayah tertentu. Tidak seperti TimeZone yang menentukan pergeseran waktu absolut, Locale menentukan bagaimana waktu, angka, dan mata uang terlihat dalam representasi string. Tanggal yang sama 2024-07-21 akan ditampilkan sebagai "21 Juli 2024" untuk ru_RU dan "July 21, 2024" untuk en_US.
Setiap instance Locale terdiri dari dua komponen: Language (bahasa — menentukan nama bulan, hari dalam seminggu, urutan kata) dan Region (wilayah — menentukan format angka, mata uang, kalender). Kombinasi komponen ini dikodekan dalam pengenal sesuai standar BCP 47: ru_RU (bahasa Rusia, Rusia), en_US (Inggris, AS), de_DE (Jerman, Jerman).
Menurut Unicode CLDR (2024), daftar lokal yang didukung di iOS melebihi 700 kombinasi bahasa-wilayah. Foundation menggunakan data dari CLDR (Common Locale Data Repository) — repositori data lokalisasi paling lengkap yang didukung oleh Unicode Consortium. Ini menjamin keseragaman format di semua perangkat Apple.
DateFormatter menggunakan Locale untuk memilih nama bulan dan hari yang benar, menentukan urutan komponen tanggal (hari/bulan/tahun atau bulan/hari/tahun) dan pemisah. Tanpa menentukan Locale secara eksplisit, DateFormatter menggunakan lokal perangkat — ini benar untuk UI, tetapi berbahaya untuk data server yang formatnya harus tetap.
| Komponen | ru_RU | en_US | de_DE |
|---|---|---|---|
| Tanggal (medium) | 21 Juli 2024 | Jul 21, 2024 | 21.07.2024 |
| Angka (1000.5) | 1.000,5 | 1,000.5 | 1.000,5 |
| Mata Uang (100) | 100,00 ₽ | $100.00 | 100,00 € |
| Kalender | Gregorian | Gregorian | Gregorian |
| Pemisah daftar | ; | , | ; |
NumberFormatter menggunakan Locale untuk menentukan pemisah desimal (koma atau titik), pemisah pengelompokan (spasi, koma, titik), dan simbol mata uang. Mengabaikan Locale saat parsing angka adalah salah satu penyebab umum bug di aplikasi internasional: angka "1,5" berarti "satu setengah" untuk ru_RU, tetapi untuk en_US penganalisis angka akan membacanya sebagai "lima" setelah koma.
Penting: Calendar yang dibuat melalui Calendar.current mewarisi lokal perangkat. Calendar(identifier: .gregorian) dengan locale yang ditentukan secara eksplisit — cara yang direkomendasikan untuk format yang dapat diprediksi. Saat bekerja dengan tanggal ISO 8601, selalu gunakan Locale(identifier: "en_US_POSIX") — lokal khusus untuk format teknis yang tidak terpengaruh oleh pengaturan regional.
Pengenal Locale terdiri dari kode bahasa (ISO 639-1, dua karakter) dan kode wilayah (ISO 3166-1, dua karakter), dipisahkan oleh garis bawah. Contoh: ru_RU, en_US, fr_FR, zh_Hans_CN (Mandarin, aksara sederhana, Cina). Foundation juga mendukung pengenal dalam format BCP 47: ru-RU, en-US, yang digunakan dalam standar web.
Selain pengenal lengkap, Locale dapat dibuat hanya berdasarkan bahasa: Locale(identifier: "ru") mengembalikan lokal dengan bahasa Rusia dan wilayah default untuk bahasa ini (biasanya Rusia). Demikian pula untuk bahasa Inggris: Locale(identifier: "en") menggunakan wilayah AS. Pendekatan ini berguna untuk mengatur bahasa format tanpa terikat ke wilayah tertentu.
Lokal khusus termasuk en_US_POSIX — lokal teknis untuk format mesin tanggal dan angka, yang menjamin format stabil terlepas dari pengaturan pengguna. Lokal ini wajib untuk parsing tanggal dari API server, terutama untuk format ISO 8601. Ini menggunakan kalender Gregorian, format waktu 24 jam, dan titik sebagai pemisah desimal.
import Foundation
// Pengenal lokal yang tersedia
let available: [String] = Locale.availableIdentifiers
print("Total lokal: \(available.count)")
// Filter lokal Rusia
let russianLocales = available.filter { $0.hasPrefix("ru") }
print("Lokal Rusia: \(russianLocales)")
// Komponen lokal
let locale = Locale(identifier: "de_DE")
print("Bahasa: \(locale.languageCode ?? "nil")")
print("Wilayah: \(locale.regionCode ?? "nil")")
print("Mata uang: \(locale.currencyCode ?? "nil")")
print("Kalender: \(locale.calendar.identifier)")
Memeriksa lokal yang tersedia melalui Locale.availableIdentifiers mengembalikan array semua pengenal yang didukung oleh versi iOS saat ini. Untuk memfilter berdasarkan wilayah, gunakan Locale.availableIdentifiers.filter dengan pemeriksaan regionCode. Ini berguna untuk membangun UI pemilihan wilayah tanpa daftar yang dikodekan secara tetap.
Locale.current — cara utama untuk mendapatkan lokal perangkat saat ini yang ditetapkan oleh pengguna di pengaturan iOS (Settings > General > Language & Region). Properti ini secara otomatis diperbarui saat bahasa atau wilayah diubah dalam pengaturan tanpa memulai ulang aplikasi. Namun, ini mungkin tidak sesuai dengan lokal yang disukai untuk menampilkan konten: pengguna dapat mengatur bahasa antarmuka ke Inggris tetapi melihat tanggal dalam format Rusia.
Untuk penentuan preferensi pengguna yang lebih akurat, gunakan Locale.preferredLanguages — array bahasa yang diurutkan berdasarkan prioritas pengguna. Elemen pertama adalah bahasa antarmuka utama. Daftar ini sesuai dengan pengaturan di Language & Region, termasuk menyeret bahasa sesuai urutan preferensi. Aplikasi komunikasi (aplikasi pesan, klien email) harus mempertimbangkan urutan ini saat memilih bahasa tampilan konten.
import Foundation
// Lokal sistem saat ini
let current = Locale.current
print("Lokal saat ini: \(current.identifier)")
print("Bahasa: \(current.language?.disjointName ?? "nil")")
// Bahasa pilihan pengguna
let preferred = Locale.preferredLanguages
print("Bahasa pilihan: \(preferred)")
// Dapatkan wilayah dari lokal saat ini
if let region = current.regionCode {
let regionLocale = Locale(identifier: "en_\(region)")
let countryName = regionLocale.localizedString(
forRegionCode: region
)
print("Negara: \(countryName ?? region)")
}
// Periksa format 24 jam
let uses24h = current.uses24hClock(
for: .dateAndTime
)
print("Menggunakan 24 jam: \(uses24h)")
Lokalisasi di UI: untuk menampilkan nama bulan dan hari dalam seminggu dalam bahasa antarmuka, gunakan Calendar dengan locale yang ditetapkan. Calendar.current.symbols(for: .month) mengembalikan nama bulan dalam bahasa lokal saat ini. Untuk menampilkan nama negara dalam bahasa pengguna, gunakan Locale.current.localizedString(forRegionCode:).
Format tanggal dengan mempertimbangkan lokal — tugas utama saat menampilkan tanggal kepada pengguna. DateFormatter dengan locale yang ditetapkan secara otomatis memilih format tanggal dan waktu yang benar untuk wilayah pengguna. Untuk dateStyle dan timeStyle dengan nilai .short, .medium, .long, .full, pemformat menggunakan aturan lokal untuk menyusun komponen tanggal.
import Foundation
let date = Date()
// Format dengan berbagai lokal
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.locale = Locale(identifier: "ru_RU")
print("Rusia: \(formatter.string(from: date))")
formatter.locale = Locale(identifier: "en_US")
print("Inggris: \(formatter.string(from: date))")
formatter.locale = Locale(identifier: "ja_JP")
print("Jepang: \(formatter.string(from: date))")
// Format mata uang dengan lokal
let numFormatter = NumberFormatter()
numFormatter.numberStyle = .currency
numFormatter.locale = Locale(identifier: "de_DE")
print("Mata uang Jerman: \(numFormatter.string(from: 1234.56) ?? "nil")")
numFormatter.locale = Locale(identifier: "en_US")
print("Mata uang AS: \(numFormatter.string(from: 1234.56) ?? "nil")")
Parsing tanggal dari API server harus selalu menggunakan Locale(identifier: "en_US_POSIX") untuk format tetap. Server biasanya mengirim tanggal dalam format ISO 8601 dengan nama bulan dalam bahasa Inggris, dan menggunakan lokal perangkat saat ini dapat menyebabkan kesalahan parsing jika pengguna berada di wilayah dengan bahasa non-Inggris. en_US_POSIX menjamin bahwa parsing tidak bergantung pada pengaturan perangkat.
import Foundation
// Parsing tanggal server yang benar
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("Tanggal yang diparsing: \(parsed)")
}
// Nama mata uang yang dilokalisasi
let usLocale = Locale(identifier: "en_US")
let currencyName = usLocale.localizedString(
forCurrencyCode: "RUB"
)
print("Rubel Rusia di lokal AS: \(currencyName ?? "nil")")
Kemampuan tambahan: Locale menyediakan deskripsi lokalisasi komponennya melalui metode localizedString(forRegionCode:), localizedString(forLanguageCode:), localizedString(forCurrencyCode:), dan localizedString(forCalendarIdentifier:). Metode ini mengembalikan nama dalam bahasa lokal tempat metode tersebut dipanggil. Misalnya, Locale(identifier: "ru_RU").localizedString(forCountryCode: "DE") akan mengembalikan "Jerman".
Mengabaikan Locale saat parsing angka — kesalahan kritis di aplikasi internasional. NumberFormatter tanpa lokal eksplisit menggunakan lokal perangkat saat ini. Jika pengguna di Rusia memasukkan "1,5", NumberFormatter.number(from: "1,5") dengan benar mengembalikan 1.5. Tetapi jika kode yang sama dijalankan di perangkat dengan lokal en_US, parsing mengembalikan nil, karena untuk en_US pemisah desimal adalah titik.
Tidak adanya en_US_POSIX untuk tanggal server menyebabkan bug yang sulit dilacak. DateFormatter dengan dateFormat dan locale = Locale.current dapat rusak pada pengguna dari wilayah yang format tanggalnya berbeda dari Amerika. Misalnya, di Jerman DateFormatter mungkin mengharapkan "21.07.2024" sementara server mengirim "07/21/2024". en_US_POSIX menjamin format tetap untuk parsing mesin terlepas dari wilayah pengguna.
Membandingkan string tanggal daripada menggunakan Date — kesalahan umum lainnya. Pengembang terkadang membandingkan representasi string tanggal dari berbagai lokal, mendapatkan hasil yang salah. Locale hanya mengubah tampilan, bukan nilai absolut tanggal. Selalu bandingkan objek Date, bukan representasi stringnya. Untuk membandingkan komponen tanggal, gunakan Calendar dengan locale yang ditentukan secara eksplisit.
Menurut WWDC 2023, sekitar 30% masalah internasionalisasi di aplikasi terkait dengan konfigurasi Locale yang salah. Apple merekomendasikan untuk selalu mengatur locale secara eksplisit untuk DateFormatter dan NumberFormatter saat bekerja dengan data server dan hanya menggunakan Locale.current untuk tampilan di UI. Praktik sederhana ini menghilangkan sebagian besar bug yang terkait dengan pengaturan regional.
Pertanyaan yang Sering Diajukan
Locale — kelas Foundation yang mewakili aturan format budaya dan linguistik: format tanggal, angka, mata uang, dan satuan ukuran. Digunakan bersama dengan DateFormatter, NumberFormatter, dan Calendar untuk tampilan data yang dilokalisasi.
Locale menentukan format tampilan (bahasa, konvensi regional), sedangkan TimeZone menentukan pergeseran waktu absolut relatif terhadap UTC. Locale memengaruhi representasi string, TimeZone — nilai numerik waktu. Keduanya digunakan bersama untuk format tanggal yang lengkap.
en_US_POSIX — lokal khusus untuk format teknis yang menjamin format stabil terlepas dari pengaturan pengguna. Wajib untuk parsing tanggal server (ISO 8601) dan bekerja dengan API yang formatnya harus dapat diprediksi.
Locale.availableIdentifiers mengembalikan array string dengan pengenal semua lokal yang didukung. Untuk memfilter berdasarkan bahasa, gunakan filter dengan hasPrefix, untuk mendapatkan wilayah — Locale(identifier:).regionCode.
NumberFormatter menggunakan Locale untuk menentukan pemisah desimal (koma atau titik), simbol mata uang, dan pemisah pengelompokan. Untuk format tetap, atur locale ke en_US_POSIX atau tentukan properti formatter secara eksplisit.
Ringkasan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga