🌍 Locale#
A simple, serializable and modern Kotlin data class for handling locales.
This library provides a type-safe alternative to java.util.Locale, designed for Kotlin Multiplatform projects.
🎯 Supported Targets#
The following targets are supported:
| Platform | Targets |
|---|---|
| JVM & Android | jvm, android |
| Apple | ios, macos, tvos, watchos |
| Web | js, wasmJs |
| Native & Other | androidNative, linux, mingw, wasmWasi |
✨ Features#
- Serializable: Annotated with
@Serializable, ready forkotlinx.serialization(JSON, Protobuf, etc.) - Rich Data Models: Provides type-safe
CountryandContinentclasses packed with useful data like ISO codes (Alpha-2, Alpha-3, Numeric), telephone codes, domains, continent codes and even emoji flags. - Flexible Parsing: Can parse locales from common language tags (e.g.
en-USorfr_CA) with customizable delimiters. - Java Interop: Seamless integration with
java.util.Localefor easy migration. - Apple Interop: Seamless integration with
Foundation.Localefor easy migration.
🚀 Installation#
Integration using Version Catalog is highly recommended for aligned version usage.
🛠️ Usage#
Creating a Locale object:
// From language and country strings
val byStrings = Locale("en", "US")
// By parsing a BCP 47 language tag (handles mixed delimiters)
val byTag = Locale.forLanguageTag("sr_Latn-RS")
// Get the system's default locale
val systemDefault = Locale()
// Using the full constructor for scripts and variants
val fullLocale = Locale(
language = "zh",
country = "CN",
script = "Hans",
variant = "PINYIN"
)
Getting Properties
Accessing Locale properties is easy:
val locale = Locale.forLanguageTag("fr-CA")
println(locale.language) // "fr"
println(locale.country) // Country object for Canada
Converting to a Language Tag
The toString() method is implemented to return a BCP 47 compliant language tag.
Receiving a Country object:
// Look up by Alpha-2, Alpha-3
// Also tries to parse numeric code
val byString = Country.forCodeOrNull("DE")
// Look up by ISO 3166-1 numeric code
val byNumber = Country.forCodeOrNull(8) // Albania
Getting Properties
Accessing the rich Country object:
val country = locale.country
if (country != null) {
println(country.emoji) // "🇨🇦"
println(country.codeAlpha3) // e.g., Code.Alpha3("CAN")
println(country.codeNumeric) // e.g., Code.Numeric("124")
println(country.telephoneCodes) // e.g., [Code.Telephone("+1")]
println(country.continent) // Continent object for Country
}
Code Types
All code types (Code.Alpha2, Code.Alpha3, Code.Numeric, etc...) implement either a CharSequence or extend Number.
This decision was made to be as flexible as possible instead of simply providing a String, while providing and keeping easy usage.
Receiving a Continent object:
// Look up by GeoName or STANAG code
// Also tries to parse UN M49 code
val byString = Continent.forCodeOrNull("EU") // Europe
// Look up by UN M49 code
val byNumber = Continent.forCodeOrNull(142) // Asia
Getting Properties
Access nested Continent data:
Code Types
All code types (Code.GeoName, Code.STANAG, Code.Numeric) implement either a CharSequence or extend Number.
This decision was made to be as flexible as possible instead of simply providing a String, while providing and keeping easy usage.