Java Locale: A Comprehensive Guide

A Java Locale (java.util.Locale) represents an object that wraps information about a specific geographical, political, or cultural region, so an object useful for internationalization purposes.

Learn about Localization and Internationalization in Java using the Locale class. Learn to create Locale objects and use them for formatting the date, number, currency, and messages.

1. Introduction to Locale

We will need to work with Java Locale api when we want to display numbers, dates, and times in a user-friendly way that conforms to the language and cultural expectations of our customers. In Java, java.util.Locale class represents a specific language and region of the world.

If a class varies its behavior according to Locale, it is said to be locale-sensitive. Some of the locale-sensitive classes defined in Java are:

  • DateFormat or DateTimeFormatter: formatting rules of the date and time information
  • NumberFormat or DecimalFormat: formatting rules of the numbers
  • MessageFormat: formatting rules of the string messages

A Locale object logically consists of fields like language, script, country, variant and extensions.

//Locale enUsLocale = new Locale("EN", "US");  // Deprecated in Java 19
Locale enUsLocale = Locale.of("EN", "US");  // Since Java 19

System.out.println(enUsLocale.toLanguageTag());  //en-US
System.out.println(enUsLocale.getDisplayName());  //English (United States)
System.out.println(enUsLocale.getDisplayLanguage());  //English
System.out.println(enUsLocale.getDisplayCountry());  //United States

To use the Locale, its instance is passed to the application components that need to localize their actions, for example parsing the input, formatting the output, or other internal operations. The Locale class does not provide methods to do any internationalization or localization tasks by itself.

2. Creating the Locale Instance

We can create a locale instance in the following ways:

2.1. Inbuilt Constants

This one is the easiest and uses predefined constants in Locale class. For example, Locale.US. Please note that when the locale is built this way then the region portion of the Locale is undefined.

So below both statements are essentially equal:

//Region is missing in both cases
Locale usLocale = Locale.US;       //1
Locale usLocale = new Locale.Builder().setLanguage("en").build();        //2

Java program to display currency and time in US locale.

Locale usLocale = Locale.US;
 
long number = 123456789L;
NumberFormat nf = NumberFormat.getInstance(usLocale);
System.out.println( nf.format(number) );     //123,456,789
 
Date now = new Date();
DateFormat df = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, usLocale);
System.out.println( df.format(now) );    //July 19, 2016 12:43:12 PM IST

2.2. Locale Constructors (Deprecated in Java 19)

There are three constructors available in the Locale class:

  • Locale(String language)
  • Locale(String language, String country)
  • Locale(String language, String country, String variant)
Locale usLocale = new Locale("en");
//or
Locale usLocale = new Locale("en", "US");

2.3. Locale.of() Methods [Since Java 19]

Starting with JDK 19, the three constructors of Locale have been deprecated and we can rely on three static of() methods instead.

The equivalent of the previous code via the proper of() method is:

Locale ro = Locale.of("en");
Locale ro = Locale.of("en", "US");

2.4. Locale.Builder

The Locale.Builder utility class can be used to construct a Locale object that conforms to the IETF BCP (Best Common Practices) 47 syntax.

This method will return java.util.IllformedLocaleException error if its argument is not a well-formed element of the BCP 47 standard.

Locale usLocale = new Locale.Builder()
        .setLanguage("en")
        .setRegion("US")
        .build();

2.5. Locale.forLanguageTag() Factory Method

If you have a language tag string that conforms to the IETF BCP 47 standard, you can use the forLanguageTag(String) factory method.

Locale usLocale = Locale.forLanguageTag("en-US");

This can especially be useful to represent complex tags such as China-specific Chinese, Mandarin, Simplified script, “zh-cmn-Hans-CN“.

Locale locale = Locale.forLanguageTag("zh-cmn-Hans-CN");

2.6. Language Ranges

Java supports language ranges which means that we can define a set of language tags that share some specific attributes. For instance, “de-*” represents a language range to recognize German in any region.

Locale.LanguageRange lr = new Locale.LanguageRange("de-*", 1.0);

The Locale.LanguageRange() constructor takes two arguments: the language range and its weight (1.0, 0.5, 0.0). The weight reveals the user’s preference (1.0 highest, 0.0 lowest) and is useful for defining priority lists.

For example, we prefer Castilian Spanish (Spain) over Mexican Spanish over Brazilian Portuguese):

String rangeString = "es-ES;q=1.0,es-MX;q=0.5,pt-BR;q=0.0";

List<Locale.LanguageRange> priorityList = Locale.LanguageRange.parse(rangeString);

3. Setting the Default Locale

Though it’s possible to set Locale in all locale-sensitive classes in runtime, but if we can set the default locale for each user request in the start (or locale-specific to the application) then we do not need to set locale for each locale-sensitive object in the application code and thus we can avoid many lines of code – and so few defects as well.

3.1. Using Locale.setDefault()

Use the Locale.setDefault() method to set the Locale instance that all locale-sensitive classes will use by default.

Locale.setDefault(Locale.FRANCE);

3.2. Setting Locale Categories

This is entirely possible to use the mixed locale formatting rules. The Locale class also allows us to set the default Locale for two different categories, separately.

The locale categories are represented by the Locale.Category enumeration:

  1. Locale.Category.DISPLAY – for the application’s user interface e.g. resource bundle messages.
  2. Locale.Category.FORMAT – for date, number, and currency formatting depending on specific region information
Locale.setDefault(Locale.Category.DISPLAY, Locale.US);

Locale.setDefault(Locale.Category.FORMAT, Locale.FR);

4. Using Locale

4.1. Using ResourceBundle

Java program to get the localized messages from the resource bundle. Do not forget to create locale-specific property files and a default property file.

  • error.messages.properties
  • error.messages_en.properties
  • error.messages_es.properties, etc.
Locale locale = new Locale("en", "US");
ResourceBundle labels = ResourceBundle.getBundle("error.messages", locale);

System.out.println(labels.getString("resource.not.found"));

4.2. Using DateFormat

Java program to get the Date format to the local display pattern.

Locale locale = new Locale("en", "US");
DateFormat df = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);

System.out.println( df.format(new Date()) );  //February 24, 2022 at 10:13:01 PM IST

4.3. Using NumberFormat

Similarly, we can format the numbers according to Locale.

 NumberFormat nf = NumberFormat.getInstance(locale);
 
System.out.println(nf.format(123456789L));   //123,456,789

Let us see an example of formatting a number as currency.

NumberFormat cf = NumberFormat.getCurrencyInstance(locale);
String currency = cf.format(123.456);
System.out.println(currency);   //$123.46

Happy Learning !!

Resources:

ISO Country Codes
ISO Language Codes

Sourcecode Download

Comments

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.

Our Blogs

REST API Tutorial

Dark Mode

Dark Mode