Locale Class in Java

Naveen AnamaneniUpdated · 5 min read

A Locale object represents a specific language, country or region, such as "English in the United States" or "Hindi in India". It doesn't hold any text or formats itself. It is an identifier that you pass to other classes, such as NumberFormat, DateTimeFormatter and ResourceBundle, so they know which rules and translations to use. The class is java.util.Locale, and its objects are immutable. In this lesson, you will learn the parts of a locale, the ways to create one, how to read its names, and how the default locale works.

The Parts of a Locale

PartExampleStandard
Languageen, de, hi, teTwo or three lowercase letters (ISO 639)
Country / regionUS, DE, INTwo uppercase letters (ISO 3166)
Script (optional)Latn, DevaFour letters
Variant and extensions (optional)u-nu-deva (use Devanagari digits)

Written together as a language tag, they look like en-US, hi-IN or fr-CA.

Ways to Create a Locale

WayExampleNotes
ConstantsLocale.US, Locale.GERMANY, Locale.FRENCHAvailable for common languages and countries only
Locale.of(...)Locale.of("hi", "IN")The modern factory method (Java 19)
Locale.forLanguageTag(tag)Locale.forLanguageTag("fr-CA")From a standard tag, such as a browser sends
Locale.Buildernew Locale.Builder().setLanguage("te").setRegion("IN").build()Validates each part
Constructorsnew Locale("hi", "IN")Deprecated since Java 19; use Locale.of

Constants come in two kinds: a language alone, such as Locale.GERMAN (de), and a language with a country, such as Locale.GERMANY (de-DE).

Methods

MethodDescription
getLanguage(), getCountry()They are used to get the codes, such as hi and IN.
getDisplayLanguage(inLocale), getDisplayCountry(inLocale)They return readable names in a chosen language.
getDisplayName(inLocale)It returns the full readable name.
toLanguageTag()It returns the standard tag, such as hi-IN.
Locale.getDefault(), Locale.setDefault(locale)They read and change the JVM's default locale.
Locale.getAvailableLocales()It returns every locale the JDK has data for.

Example: Creating and Reading Locales

Locales.java▶ Try it
import java.util.Locale;
 
public class Locales {
    public static void main(String[] args) {
        Locale india = Locale.of("hi", "IN");
        System.out.println(india + " | " + india.toLanguageTag());
        System.out.println("language: " + india.getLanguage()
            + " -> " + india.getDisplayLanguage(Locale.ENGLISH));
        System.out.println("country:  " + india.getCountry()
            + " -> " + india.getDisplayCountry(Locale.ENGLISH));
        System.out.println("name in English: "
            + india.getDisplayName(Locale.ENGLISH));
        System.out.println("name in German:  "
            + india.getDisplayName(Locale.GERMAN));
        System.out.println("name in Hindi:   "
            + india.getDisplayName(india));
 
        Locale fromTag = Locale.forLanguageTag("fr-CA");
        System.out.println(fromTag.getDisplayName(Locale.ENGLISH));
 
        Locale built = new Locale.Builder()
            .setLanguage("te").setRegion("IN").build();
        System.out.println(built.toLanguageTag() + " = "
            + built.getDisplayName(Locale.ENGLISH));
 
        System.out.println(Locale.GERMANY.equals(Locale.of("de", "DE")));
        System.out.println(Locale.GERMAN + " vs " + Locale.GERMANY);
 
        // Rules that depend on the language.
        System.out.println("TITLE".toLowerCase(Locale.ROOT)
            + " / " + "TITLE".toLowerCase(Locale.of("tr", "TR")));
 
        System.out.println("Installed locales: more than 100? "
            + (Locale.getAvailableLocales().length > 100));
    }
}
Output
hi_IN | hi-IN
language: hi -> Hindi
country:  IN -> India
name in English: Hindi (India)
name in German:  Hindi (Indien)
name in Hindi:   हिन्दी (भारत)
French (Canada)
te-IN = Telugu (India)
true
de vs de_DE
title / tıtle
Installed locales: more than 100? true

Explanation:

  • toString() gives hi_IN with an underscore, the older form. toLanguageTag() gives hi-IN, the standard form to store and exchange.
  • Display names can be requested in any language: "Hindi (India)" in English, "Hindi (Indien)" in German, and in Hindi itself.
  • forLanguageTag and the builder create the same kind of object from different inputs.
  • Equality: two locales with the same parts are equal.
  • Locale.GERMAN vs Locale.GERMANY: de is the language anywhere; de_DE is German as used in Germany. They can differ in formats: Germany and Switzerland write numbers differently.
  • Case rules depend on the language. In Turkish, the lowercase of I is the dotless ı, so "TITLE".toLowerCase(turkish) gives tıtle. For text that isn't for people, such as keys, file names and protocol words, use Locale.ROOT, the neutral locale.

The Default Locale

Every JVM has a default locale, taken from the operating system's settings at startup. Methods that don't receive a locale use it: String.format("%,d", n), NumberFormat.getInstance(), toLowerCase().

SituationWhat to use
A desktop program for one userThe default locale is usually right
A server with many usersEach user's own locale, passed explicitly
Text read by programs (keys, JSON, logs)Locale.ROOT

Common Mistakes

Using new Locale(...). It is deprecated; use Locale.of.

Confusing language with country. Locale.FRENCH and Locale.FRANCE are different, and so are en-US and en-GB.

Calling toLowerCase() or toUpperCase() without a locale on identifiers. On a Turkish system, "ID".toLowerCase() isn't "id". Use Locale.ROOT.

Storing toString() and reading it back with forLanguageTag. hi_IN isn't a valid tag; store toLanguageTag().

Interview Corner

What is the Locale class in Java?

java.util.Locale represents a specific geographical, political or cultural region, identified mainly by a language code and an optional country code (plus optional script, variant and extensions). It contains no data itself; locale-sensitive classes such as NumberFormat, DateTimeFormatter, ResourceBundle and Collator take a Locale to decide how to behave. Locales are created from constants like Locale.US, with Locale.of(language, country), Locale.forLanguageTag("en-US") or Locale.Builder; the constructors are deprecated since Java 19. Locale.getDefault() returns the JVM's default.

Practice

  1. Easy: Print the display name of Locale.JAPAN in English, in French and in Japanese.
  2. Harder: Print every available locale whose country is IN, with its language tag and English display name, sorted by tag.

Quick check: Locale

4 questions
1What does a Locale hold?
2Which is the modern way to create a Hindi (India) locale?
3What does toLanguageTag() return for Locale.US?
4Which locale should you use for lowercase conversion of a protocol keyword?

Key Takeaways

Was this tutorial helpful?

Lesson 503 of 578