i18n-timezones

March 8, 2026 ยท View on GitHub

Hex.pm License: MIT

Localized timezone names for Elixir -- 36 locales, 152 timezones, zero runtime complexity.

Building a timezone picker? Displaying meeting times across regions? Your users expect to see "Eastern Time (US & Canada)" -- in their own language, not as a raw IANA identifier.

i18n_timezones provides human-friendly, localized timezone display names sourced from CLDR, the same data that powers ICU, Chrome, and Android. All translation data comes from the i18n_timezones_data package -- no external files to manage.

Why i18n_timezones?

  • 36 locales covering 4+ billion speakers -- from Arabic to Vietnamese
  • CLDR-sourced -- accurate, professionally reviewed translations
  • ETS-backed -- concurrent reads with zero bottleneck, powered by OTP
  • Register what you need -- load individual locales or all at once
  • No panic -- all lookups return nil for missing data, mutations return {:error, reason}
  • Minimal dependencies -- only jason for JSON parsing

Install

def deps do
  [
    {:i18n_timezones, "~> 0.1"}
  ]
end

Quick Start

I18nTimezones.register_locale("de")
I18nTimezones.set_default_locale("de")

I18nTimezones.get_translation("Tokyo")
#=> "Tokio"

Usage

Register only what you need

I18nTimezones.register_locale("de")
I18nTimezones.register_locale("fr")

I18nTimezones.get_translation_for_locale("de", "Tokyo")
#=> "Tokio"

I18nTimezones.get_translation_for_locale("fr", "Tokyo")
#=> "Tokyo"

Register all locales at once

I18nTimezones.register_all_locales()
# All 36 locales now available

Using a default locale

I18nTimezones.register_locale("de")
I18nTimezones.set_default_locale("de")

I18nTimezones.get_translation("Tokyo")   #=> "Tokio"
I18nTimezones.get_translation("Berlin")  #=> "Berlin"

List available and registered locales

I18nTimezones.available_locales()    # all 36 locales in the data package
I18nTimezones.registered_locales()   # only the ones you've loaded

API Reference

FunctionDescription
register_locale(locale)Load translations for a single locale. No-op if already registered.
register_all_locales()Load all 36 available locales.
set_default_locale(locale)Set the default locale. Returns {:error, reason} if not registered.
get_default_locale()Get the current default locale, or nil.
get_translation(key)Get the localized name using the default locale.
get_translation_for_locale(locale, key)Get the localized name for a specific locale.
get_all_translations(locale)Get all translations for a locale as {:ok, map}.
available_locales()List all locales in the data package.
registered_locales()List all currently loaded locales.

All lookups return nil when a timezone or locale is not found -- no exceptions.

Supported Locales

36 locales covering major world languages:

arbncacsdadeel
eneseufifrhehi
hrhuiditjakoms
nlnoplptpt-BRroru
sqsvthtrukvizh-CN
zh-TW

Data Source

All translations come from the Unicode CLDR (Common Locale Data Repository) -- the industry-standard source used by every major platform including iOS, Android, Chrome, and Java.

Also Available For

  • Ruby -- Rails gem with automatic time_zone_select integration
  • JavaScript/TypeScript -- NPM package with tree-shaking and dropdown helpers
  • Go -- Go module with embedded data via go:embed
  • Rust -- Crate with compile-time embedded data

License

MIT