Skip to content
Buy me a coffee
Web Resources

Internationalization Standards & Code Snippets

Internationalization reference: ISO country codes, US states, Canadian provinces, Mexican states and time zone lists as HTML select snippets, CSV, JSON, XML and SQL, plus number, date, currency, phone and address formats by country with Java, C#, JavaScript and PHP code examples.

Your browser locale

What the JavaScript Intl API reports for the browser you are using right now (nothing is sent to a server).

Detecting…

Internationalization standards explained

i18n and l10n

Internationalization (i18n — "i", 18 letters, "n") is the engineering work that makes a product able to adapt to different languages and regions without changing its code: separating text from code, avoiding hard-coded formats, supporting Unicode, right-to-left scripts, variable-length strings and plural rules. Localization (l10n) is the subsequent work of adapting the product to one specific locale: translating the strings and choosing the right formats, symbols and conventions. A well internationalized application is localized by adding data (translations, CLDR patterns), not by adding code. A related term, globalization (g11n), is used by Microsoft for the combination of both.

Locale identifiers: BCP 47

A locale identifies a set of user preferences (language, script, region, calendar, numbering system…). The universal identifier format is a BCP 47 language tag: subtags separated by hyphens, most often language-REGION:

TagMeaningSubtags
enEnglish, no regionlanguage (ISO 639-1)
en-US, en-GB, fr-CAEnglish (United States), English (United Kingdom), French (Canada)language + region (ISO 3166-1 alpha-2)
zh-Hant-TW, sr-Latn-RSChinese in Traditional script (Taiwan), Serbian in Latin scriptlanguage + script (ISO 15924) + region
es-419Latin American Spanishlanguage + UN M.49 region code
ar-EG-u-nu-arab, en-US-u-ca-buddhistArabic (Egypt) with Arabic-Indic digits; English with the Buddhist calendarUnicode extension (-u-) from CLDR

Languages are lower case, scripts title case, regions upper case — by convention only, matching is case-insensitive. Java, .NET, JavaScript (Intl), Android and iOS all accept BCP 47 tags; POSIX systems and PHP's ext-intl use the older underscore form (fr_FR, fr_FR.UTF-8), which the Intl extension converts automatically.

The standards behind the data

StandardDefinesExamples
ISO 3166Country codes. Part 1: alpha-2, alpha-3 and numeric codes for 249 countries and territories; part 2: subdivisions (states, provinces); part 3: former countries.FR / FRA / 250; US-CA, MX-JAL
ISO 4217Three-letter currency codes (the first two letters are usually the country code) and numeric codes, plus the number of minor-unit digits.EUR, USD, JPY (0 decimals), BHD (3 decimals)
ISO 639Language codes: two-letter (639-1) and three-letter (639-2/3) codes for thousands of languages.en / eng, fr / fra, fil (Filipino, no 2-letter code)
IANA time zone database (tz, "Olson" database)Time zone identifiers of the form Area/City with their full history of UTC offsets and daylight-saving rules, updated several times a year.Europe/Paris, America/New_York, Asia/Kolkata
Unicode CLDRThe Common Locale Data Repository: the largest collection of locale data (number and date patterns, month names, plural rules, collation, currency symbols, units). It is what ICU, Java 9+, .NET on Linux/ICU mode, browsers' Intl, Android and iOS use under the hood.Pattern #,##0.###, symbols, "d MMMM y"
ISO 8601Unambiguous, sortable date and time notation used for data exchange.2024-12-25, 2024-12-25T14:30:00+01:00, P3Y6M4DT12H
ITU-T E.164International telephone numbering: +, country calling code and national number, at most 15 digits.+33123456789, +12125550123
UPU addressing standardsPostal address formats per country published by the Universal Postal Union.Postal code before or after the city, line order

Practical advice

  • Never hard-code formats. Use the formatting APIs of your platform (Intl, java.text/java.time, CultureInfo, NumberFormatter/IntlDateFormatter) with the user's locale, and let CLDR data decide where the currency symbol goes or which separator is used.
  • Store canonical values, format at display time. Keep numbers as numbers, dates as ISO 8601 / UTC timestamps with the IANA time zone name, currencies as ISO 4217 codes and phone numbers in E.164; produce the localized text as late as possible.
  • Locale ≠ region ≠ language. A user in Canada may want French; a French speaker in Switzerland writes 1'234.56. Let users choose the language separately from their country, and use the country for things that depend on it (currency, tax, address format).
  • Parse leniently, but with the locale. parseFloat("1,5") returns 1 in every language; use a locale-aware parser or accept both separators explicitly.
  • Test with "difficult" locales: German (long words, comma decimal), Arabic or Hebrew (right-to-left, different digits), Japanese (no spaces, different name order), Indian English (lakh/crore grouping), and Norwegian or Finnish (unusual plurals and word orders).