Internationalization with Java Locale

Java locale is the Java way of doing internationalization and represents the user's language and region. Let's dive into the basics of Java locale and discuss its implementation in greater detail.

We emphasize quite often the importance and value of respecting the user’s language and geographical region when developing software applications. Allowing the user to communicate with the software in their own language could be a serious boost to the software’s sales. When it comes to Java, it is the concept of Java locale that spells out the internationalization process.

The Java locale consists of three main elements: language, country, and variants. Language and country are quite self-explanatory, but variant code is slightly different. Sometimes, software vendors, be it operating systems or browsers, can use the code for additional functionalities. In Java locale, you can provide these additional details using variant codes. An example of a locale with three components would be de_DE_WIN – a locale for Windows for German speakers in Germany.

What Is Locale Object?

The concept of Java locale is implemented by the java.util.Locale  class. To define the locale for the application(language, country, and variant), you would use the Locale object, which is only an identifier. Real localization is done by locale-sensitive classes. Objects that you create from locale-sensitive classes customize themselves as to how to format and present data to the user. These classes use the Locale object to understand which locale is being used in the application; a good example would be the NumberFormat class. Thus, NumberFormat may return a number as 302 400 for France; 302 .400 for Germany; 302, 400 for the United States.

Some of the Local-sensitive classes defined in the Java Standard API are:

  • NumberFormat
  • DateFormat
  • DecimalFormat

Creating Java Locale Objects

Let’s dive into the code now. There are four ways to create Locale objects.

  • Locale Constructors
  • Locale.Builder Class
  • Locale.forLanguageTag Factory Method
  • Locale Constants

Using Locale Constructors

There are three constructors available for the creation of Locale objects.

  • Locale(String language) – you can use only the language to create the locale object: Locale locale = new Locale("en");
  • Locale(String language, String country) – you can use both language and country to create the locale object: Locale locale = new Locale("en", "US");
  • Locale(String language, String country, String variant) – you can use all three components – language, country, and variant – to create the locale object: Locale locale = new Locale("en", "US", "SiliconValley");

Here’s a complete example of using Locale constructors:

In the output, you can see how German and US English display large numbers and dates:

123.456.789

123,456,789

March 28, 2019 12:30:07 PM UTC

28. März 2019 12:30:07 UTC

Using Locale.Builder class

You can also use the Locale.Builder class to createLocale objects. This class has only one constructor and doesn’t take any arguments. You have to use a chain of setter methods to specify the language, country, and variant.

Using the Locale.forLanguageTag Factory Method

IETF BCP 47 is a standard that defines Language tags to identify locales, and the Java SE 7 package conforms to it. You can use the IETF BCP 47 standard language tags to create Locale objects with the Locale.forLanguageTag Factory Method. For example:

We will go through language tags later on; the code below shows you how to use the Locale.forLanguageTag Factory Method to create locale objects.

The output would be:

123.456.789

123,456,789

Locale Constants

This is probably the easiest way to create the Locale object. To make things more convenient, Java has pre-defined constants for some languages and countries. For instance: Japan is the constant for Japan, the country, while Japanese is the constant for the Japanese language. You simply need to use a constant to create a locale of that kind. The following code is an example of how to use Locale constants.

This code basically does the same thing as the previous example, the only difference is how it creates the Locale object. The output is:

123.456.789

123,456,789

Java Locale Codes

You might have noticed that we are using codes when creating objects with Locale constructors and the Locale.Builder method. There is a list of available Language codes and Country codes for Java. A full list of available codes will make this article unnecessarily long. What you get to see here is an overview of the more common ones:

Language codes:

  • English – en
  • German – de
  • French – fr
  • Russian –ru
  • Japanese – ja
  • Chinese – zh
  • Arabic – ar

The same language could be spoken in several countries. How the language is used could be different from country to country. For instance, English used in the USA is different from the English used in the UK. That’s why it’s important to specify the country in your Locale object. The country is specified with unique country codes…

Country codes:

  • United States – US
  • Germany – DE
  • France – FR
  • United Kingdom – UK
  • Canada – CA

Java Locale Language Tags

Language tags are strings with a special format used to give information on a particular locale. It can be as simple as “en” for English or as complex as “zh-cmn-Hans-CN” for Chinese, Mandarin, Simplified script, used in China.

Language tags are used by Locale.forLanguageTag(LanguageTag) to create Locale objects.

This code does nothing but creating a Locale object using the “en-US” language tag.

Language Ranges

Language range is a set of Language tags that share certain attributes. For example, “es-*” can be used to recognize Spanish in any region.

TheLocale.LanguageRange constructor used in the above example takes two arguments. The first argument is the language range, and the second argument is weight. Usually, this weight is used to express the user’s preference. In this example, we’ve created three ranges from the highest user preference to the lowest user preference.

Creating Priority Lists

You can create a priority list using a set of language ranges.

rangeString is a valid string with set of locales and their weights. Then we parse it using the parse() method in Locale.LanguageRange class to create a Language priority list.

Using Priority Lists to Filter Tags

In the previous example, we created a Language priority list. In the Language tag filtering process, we match a set of language tags against a Priority list.

The output of this program is:

en_US

en_GB

The Scope of Locale

One of the most important aspects of using locale in Java is its scope. You don’t have to use the same locale in one single program. Actually, you can give a different locale to each locale-sensitive object used in your application.

An interesting case would be the development of distributed applications. Suppose your application receives requests from different countries. How do you decide on the locale of the application? What you can do here is using separate threads to serve requests and assign a locale for each thread.

Retrieving Locale Information

The Locale object offers many methods for obtaining information about the locale being used. Let’s get to know some of them.

Get the Language of the Locale

ThegetLanguage() and getISO3Language() method can be used to retrieve the language of the locale. Here, getLanguage() returns an ISO2 letter while getISO3Language() an ISO3 letter.

The output is:

Locale: de

ISO 2: de

ISO 3: deu

First, I created a locale object using Locale constants. Then, I called the getLanguage() method on that object. It returns an ISO2 code for the German language which is de. Next, I called locale.getISO3Language(). It returned an ISO3 code for the German language which is deu.

Get the Country of the Locale

ThegetCountry() and getISO3Country() can be used to retrieve the language of the locale. Here, getCountry() returns ISO2 letter while getISO3Country() returns ISO3 letter.

The output of this code will be quite similar to the previous example:

Locale: de_DE

ISO 2 letter: DE

ISO 3 letter: DEU

If you check the output in the above examples, those short form tags are not suitable for users. Java Local object provides methods which return that above details in more readable fashion. 

Get Display Language

The getDisplayLanguage method is used to get the language in a more common fashion. There are two overriding getDisplayLanguage methods. If you use an empty-argument method, it will return the value in the default locale. If you pass the target locale as an argument, this method will return value from target locale.

Output :

German

Deutsch

In the first case, you haven’t passed any argument to the getDisplayLanguage method. Therefore, the locale value (German) is displayed in the default locale, which is en_US. Next, I attributed the target locale to the getDisplayLanguage method. Therefore Deutsch is displayed.

Get Display Country

The getDisplayCountry Method will return the locale called in a readable form. The getDisplayCountry Method works similarly to the getDisplayLanguage Method.

The output will be quite similar to the previous example, except that this time the country will be displayed.

Get Display Name

The getDisplayName method can be used to get the full locale name on which it is called. It works similar to the previous two methods:

The output would look like this:

German (Germany)

Deutsch (Deutschland)

Wrapping Up

If you are comfortable with Java internationalization, you may want to go a few steps further and learn how to internationalize JSP applications or how to internationalize a Spring boot application. If you find it difficult to Internationalize your Java application, read this article to find out if you can make use of a professional localization service. PhraseApp can help you to manage your localization projects in many ways. Beside Java, PhraseApp also supports other programming languages including PHP, Python, Ruby or JavaScript. Sign up for a free 14-day trial and try it for yourself.

Internationalization with Java Locale
5 (100%) 18 votes
Author
Shanika PhraseApp Content Team
Comments