Internationalization
Internationalization is what you do to a Java application to make it able to
handle different languages, number formats etc.
Localization is what the Java application does when it adapts itself to a user
with a specific language, number format, date and time etc.
Internationalization and localization are thus two sides of the same story. Your
Java application needs to be internationalized to in order to be able to localize
itself.
Internationalization is often abbreviated i18n. The 18 refers to the 18
characters between the first letter i, and the last letter n. Localization is
similarly abbreviated as L10n.
Internationalizing a Java application typically means making the application
able to handle multiple languages, number formats, date formats etc.
Basically, your application should be able to handle international input, output
and operations. In other words, your application should be able to adapt itself
to input, output and operations specific to different locations and user
preferences.
Your application should be able to handle international input and output.
Java's Internationalization Classes
Java has a set of built-in classes that can help you handle internationalization
of your application. These classes are:
Class
Description
Locale
The Locale class represents a language and a country
or region. A Localemay also represent a certain type of
formatting - e.g. date or number formatting.
ResourceBundle
The ResourceBundle class can contain localized texts
or components (objects). You obtain
a ResourceBundle for a specific Locale, and thus
obtain texts or objects localized to that Locale.
NumberFormat
The NumberFormat class is used to format numbers
according to a certainLocale.
DecimalFormat
The DecimalFormat class is used to format numbers
according to customized formatting patterns. These
patterns are also Locale sensitive.
DateFormat
The DateFormat class is used to format dates
according to a specificLocale.
SimpleDateForma The SimpleDateFormat class is used to parse and
t
format dates according to custom formatting patterns.
These patterns are also Locale sensitive.
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)
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:
Localelocale=Locale.JAPANESE;
Locale Constructors
You can also create a java.util.Locale instance by using one of its
constructors. The constructors are:
Locale(Stringlanguage)
Locale(Stringlanguage,Stringcountry)
Localelocale=newLocale("en");//Englishlanguage
Localelocale=newLocale("en","UK");//Englishlanguage,UnitedKingdom
Localelocale=newLocale("en","CA");//Englishlanguage,Canada
Locale Builder
From Java 7 you can use the Locale.Builder class to build
a Locale instance. Here is an example:
LocalecLocale=newLocale.Builder().setLanguage("en")
.setRegion("US").build();
Locale.forLanguageTag()
The factory method Locale.forLanguageTag() can also be used to
create a Localeinstance. Here is an example:
LocaleaLocale=Locale.forLanguageTag("enUS");
Using the Locale Instance
Once you have a Locale instance you can use it as input to other
components that use a Localeto localize their functions. Here are a few
examples:
Localelocale=newLocale("da","DK");
ResourceBundleresourceBundle=
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.
Java ResourceBundle
The java.util.ResourceBundle class is used to store texts and
components that are locale sensitive.
The ResourceBundle Class Hierarchy
The ResourceBundle class has two subclasses
called PropertyResourceBundle andListResourceBundle. Here is a
diagram illustrating the class hierarchy:
ResourceBundle has the subclasses PropertiesResourceBundle and
ListResourceBundle.
The PropertyResourceBundle class stores localized texts in standard
Java property files.
You do not directly interact with these two subclasses. All interaction goes
through theResourceBundle class.
First you need a Locale instance. Then you pass that Locale instance to
theResourceBundle.getBundle() method along with the name of the
resource bundle to load. Finally you can access the localized values in
the ResourceBundle via its differentgetString() and getObject() etc.
methods.
Property Files as ResourceBundle
You can use standard property files for storing localized texts. You can load
these properties via the ResourceBundle class. Here is an example:
Localelocale=newLocale("en","US");
ResourceBundlelabels=ResourceBundle.getBundle("i18n.MyBundle",locale);
System.out.println(labels.getString("label1"));
For this example to work you should put a standard Java property file
namedMyBundle.properties in a Java package named i18n. Make sure
this property file is available on your class path when you run the above code,
meaning the property file should be located among the classes of your
application, and in the i18n package.
The name of a resource bundle is like a class name.
Thus, i18n.MyBundle means a property file
named MyBundle.properties in the package (directory) i18n.
Here is an example of what the content of the property file could look like:
label1=Label1isdone!
label2=Label2isthrough!
As is the standard with Java property files, it is a list of key and value pairs.
The key is on the left side of the = , and the value is on the right side. The
value is what you should localize, not the key.
Different Languages in Different Property Files
In order to provide strings in different languages, create a property file for
each language, and suffix them with underscore (_) and then the language
code. For instance:
MyBundle.properties
MyBundle_da.properties
MyBundle_de.properties
MyBundle_fr.properties
All of these files should be located in the same package (directory).
The file without language suffix (e.g. MyBundle.properties) is the default
property file. In case no property file is available for the language (Locale)
passed to theResourceBundle.getBundle() method, and the system has
no default Locale set (e.g. a German computer will have a German Locale as
default), this file is read and returned as aResourceBundle.
Java NumberFormat
The java.text.NumberFormat class is used to format numbers according
to a specificLocale. Different countries have different standards for how they
format numbers. In Denmark fractions of a number are separated from the
integer part using a comma. In England they use a dot.
Creating a NumberFormat
Creating a NumberFormat for a specific Locale is done like this:
Localelocale=newLocale("da","DK");
NumberFormatnumberFormat=NumberFormat.getInstance(locale);
Formatting Numbers
Formatting a number using a NumberFormatter is done using
the format() method. Here is an example:
Stringnumber=numberFormat.format(100.99);
System.out.println(number);
Using a Danish Locale, the output printed from this code would be:
100,99
Notice that numbers like 100.00 might be formatted without the decimals,
as 100.
Formatting Currencies
To format a number as currency you need a
currency NumberFormat instance. You create a
currency NumberFormat using the getCurrencyInstance() like this:
NumberFormatcurrencyFormat=NumberFormat.getCurrencyInstance(locale);
Formatting a number as a currency is still done using the format() method.
Here is an example:
Stringcurrency=currencyFormat.format(100.999);
System.out.println(currency);
The output printed from this code would be:
kr101,00
Formatting Percentages
To format a number as percentage you need a
percentage NumberFormat instance. You create that using
the getPercentageInstance() like this:
NumberFormatpercentageFormat=NumberFormat.getPercentInstance(locale);
Formatting a number as a percentage is also done using
the format() method. Here is an example:
Stringpercentage=percentageFormat.format(99.999);
System.out.println(percentage);
The output printed from this code would be:
10.000%
Notice the % character after the number. Notice also that the number is
rounded.
Java DateFormat
The java.text.DateFormat class is used to format dates as strings
according to a specificLocale. Different countries have different standards for
how they format dates. In Denmark dates are written using the format ddmm
yyyy, but in the US they format dates using the format mmddyyyy.
Creating a DateFormat
You create a DateFormat using
the getDateInstance() and getTimeInstance()method of
the DateFormat class. Here is an example:
Localelocale=newLocale("da","DK");
DateFormatdateFormat=DateFormat.getDateInstance(
DateFormat.DEFAULT,locale);
As you can see, the getDateInstance() method takes two parameters.
The first parameter tells which date format to use. The second parameter is
the Locale to use.
The date format parameter can be chosen among the following constants in
the DateFormatclass:
DateFormat.DEFAULT
DateFormat.SHORT
DateFormat.MEDIUM
DateFormat.LONG
DateFormat.FULL
Exactly how the formatted date ends up looking for each date format used
depends on theLocale.
Formatting Dates
Formatting dates is done using the format() method. Here is an example:
Localelocale=newLocale("da","DK");
DateFormatdateFormat=DateFormat.getDateInstance(
DateFormat.DEFAULT,locale);
Stringdate=dateFormat.format(newDate());
System.out.println(date);
The output printed from this code when executed on nov. 1st 2012 would be:
01112012
If executed with a UK Locale the output would be:
Nov1,2012
Formatting Time
In order to format only time and not the date itself, you need a time instance of
the DateFormatclass. You create such an instance using
the getTimeInstance() method. Here is an example:
Localelocale=newLocale("da","DK");
DateFormatdateFormat=DateFormat.getTimeInstance(
DateFormat.DEFAULT,locale);
Stringdate=dateFormat.format(newDate());
System.out.println(date);
The output printed from that code could look like this:
12:43:37
Formatting Date and Time
Formatting a date including both date and time is done using a date-time
instance. You create such an instance using
the getDateTimeInstance() method. Here is an example:
Localelocale=newLocale("da","DK");
//Localelocale=newLocale("en","UK");
DateFormatdateFormat=DateFormat.getDateTimeInstance(
DateFormat.DEFAULT,DateFormat.DEFAULT,locale);
Stringdate=dateFormat.format(newDate());
System.out.println(date);
Notice that the getDateTimeInstance() method takes two format
parameters. One for the date, and one for the time.
Here is an example output from this code:
0111201213:07:08
Java SimpleDateFormat
The java.text.SimpleDateFormat class is used to both parse and
format dates according to a formatting pattern you specify yourself.
This text explains how to use the SimpleDateFormat class to format dates.
Creating a SimpleDateFormat
You create a SimpleDateFormat instance like this:
Stringpattern="yyyyMMdd";
SimpleDateFormatsimpleDateFormat=newSimpleDateFormat(pattern);
The pattern String parameter passed to
the SimpleDateFormat constructor is the pattern to use for parsing and
formatting of dates. The pattern syntax is covered later in this text.
Formatting Dates
Once you have created a SimpleDateFormat instance you can format
dates using itsformat() method. Here is an example:
Stringpattern="yyyyMMdd";
SimpleDateFormatsimpleDateFormat=newSimpleDateFormat(pattern);
Stringdate=simpleDateFormat.format(newDate());
System.out.println(date);
The Date instance passed to the format() method is
a java.util.Date instance.
The output printed from this code would be:
20121103
Parsing Dates
You can parse a String into a java.util.Date instance using
the parse() method of theSimpleDateFormat instance. Here is an
example:
Stringpattern="yyyyMMdd";
SimpleDateFormatsimpleDateFormat=newSimpleDateFormat(pattern);
Datedate=simpleDateFormat.parse("20121224");
Once this code is executed, the date variable points to a Date instance
representing december 24th, 2012.
Creating a SimpleDateFormat For a
Specific Locale
You can create a SimpleDateFormat instance targeted at a
specific Locale. Doing so will format the dates according to
that Locale whenever relevant. For instance, a formatting pattern including
the name of the week day will write the week day in the language of the
given Locale. Here is an example:
Stringpattern="EEEEEMMMMMyyyyHH:mm:ss.SSSZ";
SimpleDateFormatsimpleDateFormat=
newSimpleDateFormat(pattern,newLocale("da","DK"));
Stringdate=simpleDateFormat.format(newDate());
System.out.println(date);
The output printed from this code could be:
lrdagnovember201210:38:45.156+0100
Notice how week day (l = saturday) and month (november) is written in
Danish.
Pattern Syntax
You can use the following symbols in your formatting pattern:
G Era designator (before christ, after christ)
y Year (e.g. 12 or 2012). Use either yy or yyyy.
M Month in year. Number of M's determine length of format (e.g. MM, MMM
or MMMMM)
d Day in month. Number of d's determine length of format (e.g. d or dd)
h Hour of day, 1-12 (AM / PM) (normally hh)
H Hour of day, 0-23 (normally HH)
m Minute in hour, 0-59 (normally mm)
s Second in minute, 0-59 (normally ss)
S Millisecond in second, 0-999 (normally SSS)
E Day in week (e.g Monday, Tuesday etc.)
D Day in year (1-366)
F Day of week in month (e.g. 1st Thursday of December)
w Week in year (1-53)
W Week in month (0-5)
a AM / PM marker
k Hour in day (1-24, unlike HH's 0-23)
K Hour in day, AM / PM (0-11)
z Time Zone
'
Escape for text delimiter
'
Single quote
Characters other than these will be treated as normal text to insert into the
pattern, and thus into the formatted dates.
Some characters can be used in different numbers. For instance, you can
write either yy for a 2-character version of the year (e.g. 12), or you can
write yyyy for a 4-character version of the year (e.g. 2012). For more
information about the patterns accepted, see the JavaDoc for
theSimpleDateFormat class.
Pattern Examples
Here are a few patterns examples:
Pattern
Example
dd-MM-yy
31-01-12
dd-MM-yyyy
31-01-2012
MM-dd-yyyy
01-31-2012
yyyy-MM-dd
2012-01-31
yyyy-MM-dd HH:mm:ss
2012-01-31 23:59:59
yyyy-MM-dd HH:mm:ss.SSS
2012-01-31 23:59:59.999
yyyy-MM-dd HH:mm:ss.SSSZ
2012-01-31 23:59:59.999+0100
EEEEE MMMMM yyyy
HH:mm:ss.SSSZ
Saturday November 2012
10:45:42.720+0100
DateFormatSymbols
It is possible to customize the date symbols used in the formatted output, for a
specific Locale. You do so using
a java.text.DateFormatSymbols instance. Here is an example:
Localelocale=newLocale("en","UK");
DateFormatSymbolsdateFormatSymbols=newDateFormatSymbols(locale);
dateFormatSymbols.setWeekdays(newString[]{
"Unused",
"SadSunday",
"ManicMonday",
"ThrivingTuesday",
"WetWednesday",
"TotalThursday",
"FatFriday",
"SuperSaturday",
});
Stringpattern="EEEEEMMMMMyyyy";
SimpleDateFormatsimpleDateFormat=
newSimpleDateFormat(pattern,dateFormatSymbols);
Stringdate=simpleDateFormat.format(newDate());
System.out.println(date);
First a new DateFormatSymbols instance is created for the UK Locale.
Second, a new set of names for week days is set. Notice that the first
string "unused" is never used. The indices in this array must start from one,
to be indexable by the Calendar.SUNDAY,Calendar.MONDAY etc.
constants. The Calendar.SUNDAY constant is 1, Calendar.MONDAYis 2
etc.
Third a SimpleDateFormat is created using the DateFormatSymbols, and
a date is formatted with it. The output printed from this could would look like
this:
SuperSaturdayNovember2012
Notice how the custom week day name is used.
You can set more date formatting symbols on
the DateFormatSymbols instance. Here are the methods you can use to set
additional symbols:
dateFormatSymbols.setWeekdays();
dateFormatSymbols.setAmPmStrings();
dateFormatSymbols.setEras();
dateFormatSymbols.setLocalPatternChars();
dateFormatSymbols.setMonths();
dateFormatSymbols.setShortMonths();
dateFormatSymbols.setShortWeekdays();
dateFormatSymbols.setZoneStrings();