Tech and Media Labs
This site uses cookies to improve the user experience.




Java Internationalization: Locale

Jakob Jenkov
Last update: 2014-06-23

The java.util.Locale class is used to represent a "geographical, political or cultural" region to localize a given text, number, date or operation to. A Locale object may thus contain a country, region, language, and also a variant of a language, for instance a dialect spoken in a certain region of a country, or spoken in a different country than the country from which the language originates.

The Locale instance is handed to components that need to localize their actions, whether it is converting the input, output, or just need it for internal operations. The Locale class cannot do any internationalization or localization by itself.

Locale Standards

The Locale class complies with the BCP 47 (IETF BCP 47, "Tags for Identifying Languages") standard.

The Locale class also has support for the LDML (UTS#35 "Unicode Locale Data Markup Language") standard, which is a BCP 47-compatible extension for locale data exchange. See the respective standards for more information.

Locale Contents

A Locale instance contains the following subparts:

  • Language
  • Script
  • Country (region)
  • Variant
  • Extensions

Language

The language must be an ISO 639 2 or 3 character language code, or a registered language subtag of up to 8 characters. In case a language has both a 2 and 3 character language code, use the 2 character code. A full list of language codes can be found in the IANA Language Subtag Registry.

Language codes are case insensitive, but the Locale class always use lowercase versions of the language codes.

Script

The script code represents the written form of the language. Some languages can be written using different scripts (e.g. different alphabets).

The script code is a 4 character code following the ISO 15924 standard. A full list of script codes can be found in the IANA Language Subtag Registry.

Script codes are case insensitive, but the Locale class always uses a version with the first letter in uppercase, and the rest in lowercase.

Country (Region)

The country code is a 2 character code following the ISO 3166 standard, or a UN M.49 numeric area code. A full list of country and region codes can be found in the IANA Language Subtag Registry.

The country code is case insensitive, but the Locale class uses an uppercase version of the country code.

Variant

The variant part describes a variant (dialect) of a language follwing the BCP 47 standard. See the JavaDoc for the Locale class for more detail about variant.

Extensions

The extension part signals extensions to the Locale in addition to the language and region. For instance, what calendar to use when displaying dates (Gregorian, Arab, Japanese etc.). See the JavaDoc for the Locale class for more detail about extensions.

Creating a Locale

Creating a java.util.Locale instance can be done in four different ways:

  • Locale constants
  • Locale constructors
  • Locale.Builder class (from Java 7)
  • Locale.forLanguageTag factory method (from Java 7)

Each of these methods are covered in the sections below.

Locale Constants

The java.util.Locale class contains a set of constants that represent the most commonly used languages in the world. These are:

Locale.CANADA
Locale.CANADA_FRENCH
Locale.CHINA
Locale.CHINESE
Locale.ENGLISH
Locale.FRANCE
Locale.FRENCH
Locale.GERMAN
Locale.GERMANY
Locale.ITALIAN
Locale.ITALY
Locale.JAPAN
Locale.JAPANESE
Locale.KOREA
Locale.KOREAN
Locale.PRC
Locale.ROOT
Locale.SIMPLIFIED_CHINESE
Locale.TAIWAN
Locale.TRADITIONAL_CHINESE
Locale.UK
Locale.US

You use one of these constants simply by referring to it, like this:

Locale locale = Locale.JAPANESE;

Locale Constructors

You can also create a java.util.Locale instance by using one of its constructors. The constructors are:

Locale(String language)

Locale(String language, String country)

Locale(String language, String country, String variant)

The language parameter should be a 2 or 3 letter ISO language code from the ISO 639 standard. You can also use a language subtag of up to 8 characters.

The country should be a 2 character ISO country cod from the ISO 3166 standard. Alternatively a UN M.49 character area code can be used.

The variant should be any valid BCP 47 variant of a language.

Here are a few examples:

Locale locale = new Locale("en");       // English language

Locale locale = new Locale("en", "UK"); // English language, United Kingdom
Locale locale = new Locale("en", "CA"); // English language, Canada

Locale Builder

From Java 7 you can use the Locale.Builder class to build a Locale instance. Here is an example:

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

Locale.forLanguageTag()

The factory method Locale.forLanguageTag() can also be used to create a Locale instance. Here is an example:

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

Using the Locale Instance

Once you have a Locale instance you can use it as input to other components that use a Locale to localize their functions. Here are a few examples:

Locale locale = new Locale("da", "DK");

ResourceBundle resourceBundle =
        ResourceBundle.getBundle("bundleName", locale);

This example creates a Locale representing the danish language in Denmark, and uses this Locale to obtain a ResourceBundle containing texts in danish.

The ResourceBundle class is covered in more detail in the text about the ResourceBundle class.

Locale Criticism

The idea of a Locale is to represent a certain language and a set of formatting of numbers and dates related to that language and possibly a country or region. However, the language, number and date formatting a user wants, may not be related to what country or region they live in.

For instance, If I am Danish but live in Spain and use a spanish netbank, that netbank may not be able to show Danish language. So, I may choose the second best language, which for me is English. Even if the netbank had Danish language, I may still, however, prefer English formatting of numbers, because being a programmer, that is the number formatting I am used to. Additionally, being a Spanish bank account, the saldo should be shown in euro. Not in GBP or DKK (Danish Kroner).

If I travel a lot I may prefer to display date and time of an application in the local time, or home time, depending on what I am trying to do. For instance, if I need to catch a train locally, I may want local time. But if I am phoning home to my family, I may want to be able to see what time it is where they are.

Finally, I may want to show how a given application works to a person who doesn't speak the language that my application is localized to (e.g. English or Danish), so I may want to temporarily change language to e.g. Spanish or German.

All in all, it doesn't make sense to try to tie too many localization settings to the language, country or region of a user. Let the user choose what language, time zone, what number formatting and date formatting to use etc. Make it changeable too, and independently of each other. Do not tie it to the home country of the user.

Jakob Jenkov




Copyright  Jenkov Aps
Close TOC