{"id":8655,"date":"2016-09-19T14:34:25","date_gmt":"2016-09-19T12:34:25","guid":{"rendered":"https:\/\/phraseapp.com\/blog\/?p=1438"},"modified":"2023-04-03T15:17:33","modified_gmt":"2023-04-03T13:17:33","slug":"a-beginners-guide-to-java-internationalization","status":"publish","type":"post","link":"https:\/\/phrase.com\/blog\/posts\/a-beginners-guide-to-java-internationalization\/","title":{"rendered":"A Beginner&#8217;s Guide to Internationalization in Java"},"content":{"rendered":"<p class=\"p2\"><b><\/b><span class=\"s1\">When developing software or websites today, an essential consideration is the <a href=\"https:\/\/phrase.com\/blog\/posts\/why-localization-is-about-survival-in-the-global-marketplace\/\">global marketplace<\/a>. As the growth of software products for global markets continues, it has become critical for companies to design products that interact with users in their native regions and languages. Software developers working on software for foreign markets should be aware of each market\u2019s customs and differences. Some of these differences can include language, punctuation, currency, dates, times, numbers, and time zones. <\/span><\/p>\n<p class=\"p3\"><span class=\"s1\">If the software will be used in international markets, the initial software design should include planning for the international requirements, such as the target market, language, and the level of the internationalization effort required. Figure 1 shows a typical internationalization and localization process during the standard software design, development, and testing process.<\/span><\/p>\n<p class=\"p3\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1460 size-full\" src=\"https:\/\/phrase.com\/wp-content\/uploads\/2016\/09\/globalization-2.png\" alt=\"Internationalization and Localization Process During Software Development | Phrase\" width=\"737\" height=\"547\" \/><\/p>\n<p class=\"p3\" style=\"text-align: center;\"><span class=\"s1\"><b>Figure 1. Internationalization and Localization Process During Software Development.<\/b><\/span><\/p>\n<p class=\"p3\"><span class=\"s1\">Creating a localized version of a software product can become problematic and unwieldy when changes need to be implemented across multiple versions. The alternative to customizing the software for each region is called <a href=\"https:\/\/phrase.com\/blog\/posts\/i18n-a-simple-definition\/\">internationalization<\/a>. Internationalization is also known as i18n, because there are 18 letters between the first &#8220;i&#8221; and the last &#8220;n.&#8221; I18N is used to define a set of source code and binary used to support all of the markets that will be sold. An example of a software that uses internationalization is Microsoft Office. Microsoft Office 97 was shipped as separate binaries, however, MS 2000 has one source code with language packs available as an add-on.<\/span><\/p>\n<p class=\"p3\"><span class=\"s1\">An internationalized program has the following characteristics:<\/span><\/p>\n<ul>\n<li class=\"li3\"><span class=\"s1\">An executable can run in a global market with the addition of localized data.<\/span><\/li>\n<li class=\"li3\"><span class=\"s1\">Elements that are specific to a local market are stored outside the source code and retrieved dynamically.<\/span><\/li>\n<li class=\"li3\"><span class=\"s1\">Culturally-dependent data appear in formats that conform to the end user&#8217;s region and language.<\/span><\/li>\n<\/ul>\n<p class=\"p5\"><span class=\"s1\">The designers of Java realized early that internationalization of Java would be an important feature of the language. Java currently supports 100 locales, depending on the Java version. Java internalization classes and methods for each locale makes internationalizing software feasible. The first step in planning to internationalize an application is identifying culturally dependent data.<\/span><\/p>\n<style type=\"text\/css\"><!--td {border: 1px solid #ccc;}br {mso-data-placement:same-cell;}--><\/style>\n<p><span class=\"s1\"><b>1. Identify Culturally Dependent Data<\/b><\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">Before starting the internationalization of an application, it will help to create a list of software attributes that will vary from one region to another. An example list is as follows:<\/span><\/p>\n<ul>\n<li class=\"li5\"><span class=\"s1\">Language<\/span><\/li>\n<li class=\"li5\"><span class=\"s1\">Dates<\/span><\/li>\n<li class=\"li5\"><span class=\"s1\">Times<\/span><\/li>\n<li class=\"li5\"><span class=\"s1\">Numbers<\/span><\/li>\n<li class=\"li5\"><span class=\"s1\">Currencies<\/span><\/li>\n<li class=\"li5\"><span class=\"s1\">Measurements<\/span><\/li>\n<li class=\"li5\"><span class=\"s1\">Phone numbers<\/span><\/li>\n<li class=\"li5\"><span class=\"s1\">Personal titles<\/span><\/li>\n<li class=\"li5\"><span class=\"s1\">Postal addresses<\/span><\/li>\n<li class=\"li5\"><span class=\"s1\">Messages<\/span><\/li>\n<li class=\"li5\"><span class=\"s1\">Colors<\/span><\/li>\n<li class=\"li5\"><span class=\"s1\">Graphics<\/span><\/li>\n<\/ul>\n<p class=\"p5\"><span class=\"s1\">Java has many classes for translating and handling internationalization to minimize the amount of new code that needs to be written to handle each item. The most important of these tasks is to specify the locales required with the use of resource bundles.<\/span><\/p>\n<p class=\"p5\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1463 size-large\" src=\"https:\/\/phrase.com\/wp-content\/uploads\/2016\/09\/image-1-chart-551x1024.png\" alt=\"Steps to Consider When Planning Software Internationalization | Phrase\" width=\"551\" height=\"1024\" \/><\/p>\n<p class=\"p5\" style=\"text-align: center;\"><span class=\"s1\"><span class=\"Apple-converted-space\">\u00a0 <\/span><b>Figure 2. Initial Steps to Consider When Planning the Internationalization Process During Software Development.<\/b><\/span><\/p>\n<p><span class=\"s1\"><b>2. Use Resource Bundles<\/b><\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">The first step in internationalization is isolating text that can be translated into ResourceBundle objects. The text includes GUI labels, status and error messages, and help files. Applications that are not internationalized have text hard-coded into the code. For additional information on ResourceBundle objects, go to the section on Isolating Locale-Specific Data for details.<\/span><\/p>\n<p><span class=\"s1\"><b>3. Deal with Compound Messages<\/b><\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">Compound messages have constituents that need to be translated into locale-specific code, and cannot be handled by resource bundles alone. Compound messages often have a combination of words and numbers that need to be translated. Additional information can be found in the Messages section of this tutorial.<\/span><\/p>\n<p><span class=\"s1\"><b>4. Format Numbers, Currencies, and Percentages<\/b><\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">Numbers and currencies may need to be displayed in a specific manner, depending upon the locale. These classes are discussed in greater detail in the Numbers and Currencies section.<\/span><\/p>\n<p><span class=\"s1\"><b>5. Format Dates and Times<\/b><\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">The format of dates and times differ with region and language. Using Java&#8217;s date-formatting classes will enable you to display dates and times correctly around the world. For additional information, see the section Dates and Times. <\/span><\/p>\n<p><span class=\"s1\"><b>6. Use Unicode Character Properties<\/b><\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">When comparing characters in languages other than English, the <a href=\"https:\/\/phrase.com\/blog\/posts\/unicode\/\">Unicode standard<\/a> should be used to identify character properties. For information on character comparison methods, see the section on Checking Character Properties.<\/span><\/p>\n<p><span class=\"s1\"><b>7. Compare Strings Properly<\/b><\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">When sorting text, it is normal to compare strings. The standard string comparison classes, String.equals and String.compareTo methods perform binary comparisons, which are not effective in many languages. The Collator class should be used to compare strings in foreign locales. For additional information, review the section on Comparing Strings. <\/span><\/p>\n<p><span class=\"s1\"><b>8. Convert Non-Unicode Text<\/b><\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">Characters in the Java programming language are encoded in Unicode. If your application handles non-Unicode text, you might need to translate it into Unicode. For additional information, review the section on Converting Non-Unicode Text.<\/span><\/p>\n<style type=\"text\/css\"><!--td {border: 1px solid #ccc;}br {mso-data-placement:same-cell;}--><\/style>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_69_1 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Overview<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/phrase.com\/blog\/posts\/a-beginners-guide-to-java-internationalization\/#locales\" title=\"Locales\">Locales<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/phrase.com\/blog\/posts\/a-beginners-guide-to-java-internationalization\/#isolating-locale-specific-data-with-resource-bundles\" title=\"Isolating Locale-Specific Data with Resource Bundles\">Isolating Locale-Specific Data with Resource Bundles<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/phrase.com\/blog\/posts\/a-beginners-guide-to-java-internationalization\/#an-example-program-before-and-after-internationalization\" title=\"An Example Program: Before and After Internationalization\">An Example Program: Before and After Internationalization<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/phrase.com\/blog\/posts\/a-beginners-guide-to-java-internationalization\/#java-internationalizing-the-sample-program\" title=\"Java Internationalizing the Sample Program\">Java Internationalizing the Sample Program<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/phrase.com\/blog\/posts\/a-beginners-guide-to-java-internationalization\/#translating-java-applications%e2%80%94the-easy-way\" title=\"Translating Java Applications\u2014the Easy Way\">Translating Java Applications\u2014the Easy Way<\/a><\/li><\/ul><\/nav><\/div>\n<h2><span class=\"ez-toc-section\" id=\"locales\"><\/span>Locales<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p class=\"p3\"><span class=\"s1\">An internationalized program displays information differently for different users in other regions across the world. For example, an internalized program will display a message in American English for someone in the US and a message in British English to someone in the United Kingdom. The internationalized program uses a Locale object to identify the appropriate region of the end user. The locale-sensitive operations use the Locale class found in the java.util package.<\/span><\/p>\n<p><span class=\"s1\"><b>1.Creating a Locale<\/b><\/span><\/p>\n<p class=\"p5\"><span class=\"s1\">As of JDK 7, there are four methods for creating a locale:<\/span><\/p>\n<ul>\n<li class=\"li5\"><span class=\"s1\">Locale.Builder Class<\/span><\/li>\n<li class=\"li5\"><span class=\"s1\">Locale Constructors<\/span><\/li>\n<li class=\"li5\"><span class=\"s1\">Locale.forLanguageTag Factory Method<\/span><\/li>\n<li class=\"li5\"><span class=\"s1\">Locale Constants<\/span><\/li>\n<\/ul>\n<p class=\"p5\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1467 size-full\" src=\"https:\/\/phrase.com\/wp-content\/uploads\/2016\/09\/table-1.png\" alt=\"ISO-639 standard language codes | Phrase\" width=\"660\" height=\"474\" \/><\/p>\n<p class=\"p5\" style=\"text-align: center;\"><span class=\"s1\"><b>Figure 3. Four Common Methods for Creating a Locale.<\/b><\/span><\/p>\n<p class=\"p5\"><span class=\"s1\">The next few sections will show different methods for creating the Locale object and the differences between them.<\/span><\/p>\n<p><span class=\"s1\"><b>2. Using Locale Constructors<\/b><\/span><\/p>\n<p class=\"p5\"><span class=\"s1\">There are three constructors that can create a Locale object:<\/span><\/p>\n<ol class=\"ol1\">\n<li class=\"li10\"><span class=\"s1\">Locale(String language): Creates a locale from a language code.<\/span><\/li>\n<li class=\"li10\"><span class=\"s1\">Locale(String language, String country): Creates a locale from a language and then the country code.<\/span><\/li>\n<li class=\"li10\"><span class=\"s1\">Locale(String language, String country, String variant): Creates a locale from language, country, and variant.<\/span><\/li>\n<\/ol>\n<p class=\"p3\"><span class=\"s1\">The one used most often is the second constructor, where the ISO-639 language code is specified in lowercase and the ISO-3166 country code specified in uppercase. An example of creating <\/span><span class=\"s3\">Locale<\/span><span class=\"s1\"> objects for the French language in Canada, the English language in the U.S, and New York is:<\/span><\/p>\n<pre class=\"lang:default decode:true\">\/\/ Creates a locale object using a one parameter constructor\nLocale locale = new Locale(\"fr\");\u00a0\nSystem.out.println(\"locale: \"+locale);\u00a0\n\/\/ Create a locale object using a two parameter constructor\nLocale locale2 = new Locale(\"en\", \"US\");\nSystem.out.println(\"locale2: \"+locale2);\n\/\/ Create a locale object using three parameter constructor\nLocale locale3 = new Locale(\"en\", \"US\", \"NY\");\nSystem.out.println(\"locale3: \"+locale3);<\/pre>\n<p><span class=\"s1\"><b>3. LocaleBuilder Class<\/b><\/span><\/p>\n<p class=\"p3\"><span class=\"s1\">The second method of constructing a locale object is using the <a href=\"https:\/\/docs.oracle.com\/javase\/8\/docs\/api\/java\/util\/Locale.Builder.html\">Locale.Builder<\/a> utility class.<span class=\"Apple-converted-space\">\u00a0 <\/span>This class checks if the value satisfies the syntax requires defined by the locale class. The locale object created by the builder class can be transformed to the IETF BCP 47 language tag without losing information. The following example displays how to create a Locale object with the Builder for the United States:<\/span><\/p>\n<pre class=\"lang:default decode:true \">\/\/ A local object from Locale.Builder\nLocale localeFromBuilder = new Locale.Builder().setLanguage(\"en\").setRegion(\"US\").build();\nSystem.out.println(\"localeFromBuilder: \"+localeFromBuilder);<\/pre>\n<p><span class=\"s1\"><b>4. forLanguageTag Factory Method<\/b><\/span><\/p>\n<p class=\"p5\"><span class=\"s1\">The <a href=\"https:\/\/docs.oracle.com\/javase\/8\/docs\/api\/java\/util\/Locale.html#forLanguageTag-java.lang.String-\">forLanguageTag(String)<\/a> factory method is used when you have a language tag string that conforms to the IETF BCP 47 standard. An example of using this method for the United States and the English Language is as follows:<\/span><\/p>\n<pre class=\"lang:default decode:true \">\/\/Locale from forLanguageTag method\nLocale forLangLocale = Locale.forLanguageTag(\"en-US\");\nSystem.out.println(\"forLangLocale: \"+forLangLocale);<\/pre>\n<p><span class=\"s1\"><b>5. Locale Constants<\/b><\/span><\/p>\n<p class=\"p13\"><span class=\"s1\">The Locale class provides a set of pre-defined constants for some languages and countries. If a language is specified, the regional part of the local is unspecified.<\/span><\/p>\n<pre class=\"lang:default decode:true\">\/\/Using Locale Contant\nLocale localeCosnt = Locale.FRANCE;\nSystem.out.println(\"localeCosnt: \"+localeCosnt);<\/pre>\n<p><span class=\"s1\"><b>6. Codes<\/b><\/span><\/p>\n<p class=\"p3\"><span class=\"s1\">There are language, country, region, script, and variant codes. The next few sections describe each type of code and provide code examples.<\/span><\/p>\n<p><span class=\"s1\"><b>6.1 Language Codes<\/b><\/span><\/p>\n<p class=\"p3\"><span class=\"s1\">The language code consists of two or three lowercase letters that conform to the ISO-639 standard. A few of the ISO-639 language codes are shown in Table 1. <a href=\"http:\/\/www.loc.gov\/standards\/iso639-2\/php\/code_list.php\">The complete list of ISO-639 language codes is available online<\/a>.<\/span><\/p>\n<p class=\"p3\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1467 size-full\" src=\"https:\/\/phrase.com\/wp-content\/uploads\/2016\/09\/table-1.png\" alt=\"ISO-639 standard language codes | Phrase\" width=\"660\" height=\"474\" \/><\/p>\n<p class=\"p3\" style=\"text-align: center;\"><span class=\"s1\"><b>Table 1. Sample Language Codes<\/b><\/span><\/p>\n<p class=\"p3\"><span class=\"s1\">Language information can be obtained by using the following methods:<\/span><\/p>\n<p class=\"p3\"><span class=\"s1\">getISO3Language(), getDisplayLanguage(), and getDisplayLanguage(Locale<\/span><\/p>\n<p class=\"p3\"><span class=\"s1\">inLocale).<\/span><\/p>\n<p><span class=\"s1\"><b>6.2 Country Codes<\/b><\/span><\/p>\n<p class=\"p3\"><span class=\"s1\">The country (region) code conforms to the ISO 3166 standard or three numbers that conform to the UN M.49 standard. <a href=\"http:\/\/www.chemie.fu-berlin.de\/diverse\/doc\/ISO_3166.html\">The list of ISO 3166 language codes is available online<\/a>.<\/span><\/p>\n<p class=\"p3\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1468 size-full\" src=\"https:\/\/phrase.com\/wp-content\/uploads\/2016\/09\/table-2.png\" alt=\"ISO 3166 country codes | Phrase\" width=\"965\" height=\"485\" \/><\/p>\n<p class=\"p3\" style=\"text-align: center;\"><span class=\"s1\"><b>Table 2. Sample Country Codes<\/b><\/span><\/p>\n<p><span class=\"s1\"><b>6.3 Script Codes<\/b><\/span><\/p>\n<p class=\"p3\"><span class=\"s1\">The script code conforms to the ISO 15924 standard and begins with an uppercase letter followed by three lowercase letters. The <a href=\"http:\/\/unicode.org\/iso15924\/iso15924-codes.html\">list of full list of language codes can be found in the IANA Language Subtag Registry<\/a>.<\/span><\/p>\n<p class=\"p3\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1469 size-full\" src=\"https:\/\/phrase.com\/wp-content\/uploads\/2016\/09\/table-3.png\" alt=\"ISO 15924 script codes | Phrase\" width=\"661\" height=\"406\" \/><\/p>\n<p class=\"p3\" style=\"text-align: center;\"><span class=\"s1\"><b>Table 3. Sample Script Codes<\/b><\/span><\/p>\n<p><span class=\"s1\"><b>6.4 Variant Codes<\/b><\/span><\/p>\n<p class=\"p3\"><span class=\"s1\">Variants are used to specify a certain part of a locale. It can further define dialects or language variations that further define a specific region. The variant can tailor output for a specific browser or operating system. The variant part describes a variant (dialect) of a <a href=\"https:\/\/www.iana.org\/assignments\/language-subtag-registry\/language-subtag-registry\">language following the BCP 47 standard<\/a>.<\/span><\/p>\n<p><span class=\"s1\"><b>7. Locale Class Methods<\/b><\/span><\/p>\n<p class=\"p16\"><span class=\"s1\">The Locale class contains many methods that return information about the default Locale. Each time that a Java program is run, the default locale is constructed from your environment, using language and region preferences. The commonly used methods of the Locale class is as follows:<\/span><\/p>\n<ol class=\"ol1\">\n<li class=\"li10\"><span class=\"s1\">getDefault() provides the default Locale object.<\/span><\/li>\n<li class=\"li10\"><span class=\"s1\">getAvailableLocales() provides an array of available locales.<\/span><\/li>\n<li class=\"li10\"><span class=\"s1\">getDisplayCountry() provides the country name <\/span><\/li>\n<li class=\"li10\"><span class=\"s1\">getDisplayLanguage() provides the language name <\/span><\/li>\n<li class=\"li10\"><span class=\"s1\">getDisplayVariant() provides the variant code <\/span><\/li>\n<li class=\"li10\"><span class=\"s1\">getISO3Country() provides the three letter abbreviation for the current locale&#8217;s country.<\/span><\/li>\n<li class=\"li10\"><span class=\"s1\">getISO3Language() provides the three letter abbreviation for the current locale&#8217;s language.<\/span><\/li>\n<\/ol>\n<p class=\"p3\"><span class=\"s1\">The following example can be used to obtain default locale information:<\/span><\/p>\n<pre class=\"lang:default decode:true\">import\u00a0java.util.*;\npublic\u00a0class\u00a0LocaleExample\u00a0{\npublic\u00a0static\u00a0void\u00a0main(String[]\u00a0args)\u00a0{\nLocale\u00a0locale=Locale.getDefault();\n\u00a0\u00a0\nSystem.out.println(locale.getDisplayCountry());\nSystem.out.println(locale.getDisplayLanguage());\nSystem.out.println(locale.getDisplayName());\nSystem.out.println(locale.getISO3Country());\nSystem.out.println(locale.getISO3Language());\nSystem.out.println(locale.getLanguage());\nSystem.out.println(locale.getCountry());\u00a0\u00a0\u00a0\n     }\n}<\/pre>\n<p class=\"p3\"><span class=\"s1\">The output from this code will produce the following:<\/span><\/p>\n<pre class=\"lang:default decode:true\">United States\nEnglish\nEnglish (United States)\nUSA\neng\nen\nUS<\/pre>\n<h2><span class=\"ez-toc-section\" id=\"isolating-locale-specific-data-with-resource-bundles\"><\/span>Isolating Locale-Specific Data with Resource Bundles<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p class=\"p5\"><span class=\"s1\">Applications need to be tailored to provide locale-specific information according to the conventions of the end user&#8217;s language and region. Resource bundles can be used to keep text messages, formatting conventions, and images targeted to a specific locale. Resource Bundles automatically isolate the locale-specific objects so that locale-sensitive information does not need to be hardcoded into an application. Resource bundles:<\/span><\/p>\n<p class=\"p5\"><span class=\"s1\">\u2022 Allow storage and retrieval of all locale-specific information.<\/span><\/p>\n<p class=\"p5\"><span class=\"s1\">\u2022 Allow support for multiple locales in a single application.<\/span><\/p>\n<p class=\"p5\"><span class=\"s1\">\u2022 Allow the addition of locales easily by adding additional resource bundles.<\/span><\/p>\n<p class=\"p5\"><span class=\"s1\">The java.util.ResourceBundle class stores text that are locale sensitive. This section reviews the ResourceBundle class and its subclasses.<\/span><\/p>\n<p class=\"p18\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1462 size-full\" src=\"https:\/\/phrase.com\/wp-content\/uploads\/2016\/09\/image-1-1.png\" alt=\"Illustration of ResourceBundles Communicate with Applications | Phrase\" width=\"983\" height=\"668\" \/><\/p>\n<p class=\"p18\" style=\"text-align: center;\"><span class=\"s1\"><b>Figure 4. Illustration of ResourceBundles Communicate with Applications.<\/b><\/span><\/p>\n<p><span class=\"s1\"><b>1. The ResourceBundle Class<\/b><\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">The ResourceBundle class is in the java.util package and it has two subclasses: PropertyResourceBundle and ListResourceBundle. Figure 5 illustrates the class hierarchy:<\/span><\/p>\n<p class=\"p6\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1464 size-full\" src=\"https:\/\/phrase.com\/wp-content\/uploads\/2016\/09\/image-2.png\" alt=\"ResourceBundle Class hierarchy | Phrase\" width=\"916\" height=\"385\" \/><\/p>\n<p class=\"p6\"><span class=\"s1\">ResourceBundle acts like a container that holds key\/value pairs. The key identifies a specific value in a bundle. A subclass of resource bundle implements two abstract methods: getKeys and handleGetObject. The handleGetObject(String key) uses a string as its argument, and then it returns a specific value from the resource bundle. The getKeys method returns all keys from a specific resource bundle. <\/span><\/p>\n<p><span class=\"s3\"><b>1.1. Names<\/b><\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">A ResourceBundle is a set of related subclasses that share the same base name. The basename is followed by characters that specify the language code, country code, and variant of a Locale. For example, if the base name is \u201cnewResourceBundle\u201d, and there is a U.S. English and French Canada locale, then the names would look like the following:<\/span><\/p>\n<ul>\n<li class=\"li6\"><span class=\"s1\">newResourceBundle_en_US<\/span><\/li>\n<li class=\"li6\"><span class=\"s1\">newResourceBundle_fr_CA<\/span><\/li>\n<li class=\"li6\"><span class=\"s1\">newResourceBundle<\/span><\/li>\n<\/ul>\n<p class=\"p6\"><span class=\"s1\">The default Locale would be named \u201cnewResourceBundle\u201d. All of the files will be located in the same package or directory. All of the property files with a different language, country, and variant codes will contain the same keys but have values in different languages.<\/span><\/p>\n<p><span class=\"s1\"><b>1.2. Properties File<\/b><\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">A properties file (.properties) stores a collection of text elements. The PropertyResourceBundle provides the code necessary to retrieve the text elements. The properties class in the java.util package handles the reading and writing and consists of a list of key and value pairs. The values in a properties file are specified in the following format:<\/span><\/p>\n<pre class=\"lang:default decode:true \">Key = value<\/pre>\n<p class=\"p6\"><span class=\"s1\">The comment lines in a properties files have a (#) pound or (!) exclamation at the beginning of the line.<\/span><\/p>\n<p><span class=\"s1\"><b>1.3. Creating a ResourceBundle<\/b><\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">The first step in creating a ResourceBundle is to create a Local instance. The Local instance and the resource bundle to load is then passed to the ResourceBundle.getBundle() method. The getString() and getObject() values can then be used to access the localized values. An example of a ResourceBundle instance is as follows:<\/span><\/p>\n<pre class=\"lang:default decode:true\">Locale locale = new Locale(\"en\", \"US\");\nResourceBundle labels = ResourceBundle.getBundle(\"i18n.newResourceBundle\", locale);\nSystem.out.println(labels.getString(\"label\"));<\/pre>\n<p class=\"p6\"><span class=\"s1\">An instance of ResourceBundle is never created, but an instance of ListResourceBundle or PropertyResourceBundle subclass. The name of the Java property file is \u201cnewResourceBundle\u201d, and the Java package is \u201ci18n\u201d. An example of the content of the property file is as follows:<\/span><\/p>\n<pre class=\"lang:default decode:true \">label = Label 1<\/pre>\n<p class=\"p6\"><span class=\"s1\">Once you have obtained a ResourceBundle instance, you can get localized values from it using one of the methods: <\/span><\/p>\n<ul>\n<li class=\"li13\"><span class=\"s1\">getObject(String key);<\/span><\/li>\n<li class=\"li13\"><span class=\"s1\">getString(String key);<\/span><\/li>\n<li class=\"li13\"><span class=\"s1\">getStringArray(String key);<\/span><\/li>\n<\/ul>\n<p class=\"p13\"><span class=\"s1\">A set of all keys in a ResourceBundle can be obtained using the keySet() method.<\/span><\/p>\n<p><span class=\"s1\"><b>1.4. Dates and Times<\/b><\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">The format for displaying date and time varies depending on the locale. For example, 07\/03\/1977 can be interpreted as July 3, 1977, in the U.S., but would be interpreted as March 7, 1977, in Britain. The order of the fields, delimiters used and even the calendar used can vary depending on the region. The DateFormat class in java.util package provides formatting styles for a specific locale in easy-to-use formats.<\/span><\/p>\n<p><span class=\"s1\"><b>1.4.1. Formatting Dates<\/b><\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">The DateFormat class can be used to format dates, and it consists of two steps:<\/span><\/p>\n<ol class=\"ol1\">\n<li class=\"li6\"><span class=\"s1\">getDateInstance method<\/span><\/li>\n<li class=\"li6\"><span class=\"s1\">format method<\/span><\/li>\n<\/ol>\n<p class=\"p6\"><span class=\"s1\">The inputs for the getDateInstance method consist of (1) the date format to use and the (2) locale. The format method returns a string with the formatted date. The date format to use can be specified as \u201cdefault,\u201d \u201cshort,\u201d \u201cmedium,\u201d \u201clong\u201d, and \u201cfull.\u201d These five styles are specified for each locale as shown in Table 4:<\/span><\/p>\n<p class=\"p5\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1470 size-full\" src=\"https:\/\/phrase.com\/wp-content\/uploads\/2016\/09\/table-4.png\" alt=\"Date styles for U.S. Locale | Phrase\" width=\"660\" height=\"474\" \/><\/p>\n<p class=\"p5\" style=\"text-align: center;\"><span class=\"s1\"><b>Table 4. Styles for U.S. Locale.<\/b><\/span><\/p>\n<pre class=\"lang:default decode:true\">Locale locale = new Locale(\"en\", \"US\");\nDateFormat dateFormat = DateFormat.getDateInstance(\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 DateFormat.DEFAULT, locale);\nString date = dateFormat.format(new Date());\nSystem.out.println(date);<\/pre>\n<p class=\"p6\"><span class=\"s1\">The output from this code on June 24, 2016, would be:<\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">Jun 24, 2016<\/span><\/p>\n<p><span class=\"s1\"><b>1.4.2. Formatting Time<\/b><\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">The DateFormat class can also be used to format times in a similar manner using the getTimeInstance method and the format method. The time format can also be specified as \u201cdefault,\u201d \u201cshort,\u201d \u201cmedium,\u201d \u201clong\u201d, and \u201cfull.\u201d These five styles are specified for each locale as shown in Table 5:<\/span><\/p>\n<p class=\"p5\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1471 size-full\" src=\"https:\/\/phrase.com\/wp-content\/uploads\/2016\/09\/table-5.png\" alt=\"U.S. time styles | Phrase\" width=\"660\" height=\"474\" \/><\/p>\n<p class=\"p5\" style=\"text-align: center;\"><span class=\"s1\"><b>Table 5. U.S. Styles<\/b><\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">An example using the getTimeInstance and the format method is as follows:<\/span><\/p>\n<pre class=\"lang:default decode:true\">Locale locale = new Locale(\"en\", \"US\");\nDateFormat dateFormat = DateFormat.getTimeInstance(\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 DateFormat.DEFAULT, locale);\nString date = dateFormat.format(new Date());\nSystem.out.println(date);<\/pre>\n<p class=\"p6\"><span class=\"s1\">If the time is 10:30:39, then the output from the code is: <\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">10:30:39<\/span><\/p>\n<p><span class=\"s1\"><b>1.4.3. Formatting Date and Time<\/b><\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">The getDateTimeInstance method can be used to format both date and time. The inputs for the getDateTimeInstance method consist of (1) the date format to use, (2) the time format to use, and the (3) locale.<\/span><\/p>\n<pre class=\"lang:default decode:true\">Locale locale = new Locale(\"en\", \"US\");\nDateFormat dateFormat = DateFormat.getDateTimeInstance(\n\u00a0 \u00a0 \u00a0 \u00a0 DateFormat.DEFAULT,DateFormat.DEFAULT, locale);\nString date = dateFormat.format(new Date());\nSystem.out.println(date);<\/pre>\n<p class=\"p6\"><span class=\"s1\">Here is an example output from this code: <\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">Jun 24, 2016 9:08:21 AM<\/span><\/p>\n<p><span class=\"s1\"><b>1.5. Formatting Currencies<\/b><\/span><\/p>\n<p class=\"p5\"><span class=\"s1\">The <\/span><span class=\"s3\">NumberFormat<\/span><span class=\"s1\"> class can be used for formatting currencies specific to a locale, <\/span><span class=\"s3\">and it consists of two steps:<\/span><\/p>\n<ol class=\"ol1\">\n<li class=\"li5\"><span class=\"s1\">getCurrencyInstance method<\/span><\/li>\n<li class=\"li5\"><span class=\"s1\">format method<\/span><\/li>\n<\/ol>\n<p class=\"p5\"><span class=\"s1\">The input for the getCurrencyInstance method consists of the locale. The format method returns a string with the formatted currency. An example is shown below:<\/span><\/p>\n<pre class=\"lang:default decode:true\">Double currency = new Double(525,600.10);\nCurrency currentCurrency = Currency.getInstance(locale);\nNumberFormat currencyFormatter =\nNumberFormat.getCurrencyInstance(locale);\nSystem.out.println(\n\u00a0 \u00a0 \u00a0 \u00a0 currentCurrency.getDisplayName() + \": \" +\n\u00a0 \u00a0 \u00a0 \u00a0 currencyFormatter.format(currency));<\/pre>\n<p class=\"p3\"><span class=\"s1\">The output of this code is:<\/span><\/p>\n<p class=\"p3\"><span class=\"s1\">US Dollar: $525,600.10<\/span><\/p>\n<p><span class=\"s1\"><b>1.6. Number Formatting<\/b><\/span><\/p>\n<p class=\"p5\"><span class=\"s1\">The <\/span><span class=\"s3\">NumberFormat<\/span><span class=\"s1\"> class can be used for formatting numbers, currencies, and percentages according to a locale. An example of a difference in number format between countries is the use of a \u201cdot\u201d in the U.S. and England to indicate a decimal or fraction, and the use of a comma in Denmark. The NumberFormat class consists of two steps:<\/span><\/p>\n<ol class=\"ol1\">\n<li class=\"li5\"><span class=\"s2\"><a href=\"https:\/\/docs.oracle.com\/javase\/8\/docs\/api\/java\/text\/NumberFormat.html#getNumberInstance-java.util.Locale-\"><span class=\"s5\">getNumberInstance<\/span><\/a><\/span><span class=\"s1\"> method<\/span><\/li>\n<li class=\"li5\"><span class=\"s1\">format method<\/span><\/li>\n<\/ol>\n<p class=\"p13\"><span class=\"s1\">The input for the getNumberInstance method consists of the locale.<\/span><\/p>\n<pre class=\"lang:default decode:true\">Double num = new Double(525949.2);\nNumberFormat numberFormatter;\nString numOut;\nLocale locale = new Locale(\"en\", \"US\");\nnumberFormatter = NumberFormat.getNumberInstance(locale);\nnumOut = numberFormatter.format(num);\nSystem.out.println(numOut + \" \u00a0 \" + currentLocale.toString());<\/pre>\n<p class=\"p3\"><span class=\"s1\">The output of this program would format the number as follows:<\/span><\/p>\n<p class=\"p3\"><span class=\"s1\">525,949.2 en_US<\/span><\/p>\n<p><span class=\"s1\"><b>1.7. Percentages<\/b><\/span><\/p>\n<p class=\"p5\"><span class=\"s1\">The <a href=\"https:\/\/docs.oracle.com\/javase\/8\/docs\/api\/java\/text\/NumberFormat.html\">NumberFormat<\/a> class can be used to format percentages, and it consists of two steps:<\/span><\/p>\n<ol class=\"ol1\">\n<li class=\"li5\"><span class=\"s2\"><a href=\"https:\/\/docs.oracle.com\/javase\/8\/docs\/api\/java\/text\/NumberFormat.html#getPercentInstance-java.util.Locale-\"><span class=\"s5\">getPercentInstance<\/span><\/a><\/span><span class=\"s1\"> method<\/span><\/li>\n<li class=\"li5\"><span class=\"s1\">format method<\/span><\/li>\n<\/ol>\n<p class=\"p3\"><span class=\"s1\">The input for the getPercentInstance method consists of the locale. An example is as follows:<\/span><\/p>\n<pre class=\"lang:default decode:true\">Double percent = new Double(0.25);\nNumberFormat percentFormatter;\nString percentOut;\npercentFormatter = NumberFormat.getPercentInstance(currentLocale);\npercentOut = percentFormatter.format(percent);\nSystem.out.println(percentOut + \" \u00a0 \" + currentLocale.toString());<\/pre>\n<p class=\"p3\"><span class=\"s1\">The output of this program will be as follows:<\/span><\/p>\n<p class=\"p24\"><span class=\"s1\">25% <span class=\"Apple-converted-space\">\u00a0 <\/span>en_US<\/span><\/p>\n<p><span class=\"s1\"><b>1.8. Time Zones<\/b><\/span><\/p>\n<p class=\"p3\"><span class=\"s1\">If your application needs to be run in different time zones, the code needs to be written to manage dates and times in a manner that is consistent to all users. The standard method of handling this is to convert time to UTC (Coordinated Universal Time) before storing it. The time in each time zones is calculated as an offset to UTC. For example, the U.S. is UTC-5, which means that it is UTC minus 5 hours. Figure shows a diagram of the time zones:<\/span><\/p>\n<p class=\"p3\"><span class=\"s1\">The java.util.Calendar class can be used to convert between time zones.<span class=\"Apple-converted-space\">\u00a0 <\/span>The steps for using this class are as follows:<\/span><\/p>\n<ol class=\"ol1\">\n<li class=\"li3\"><span class=\"s1\">Create the calendar instance using the calendar subclass. The <\/span><span class=\"s3\">GregorianCalendar<\/span><span class=\"s1\"> is typically used.<\/span><\/li>\n<li class=\"li3\"><span class=\"s1\">Use the <\/span><span class=\"s3\">TimeZone<\/span><span class=\"s1\"> class to get the timezone.<\/span><\/li>\n<li class=\"li3\"><span class=\"s1\">Set the time in the desired timezone.<\/span><\/li>\n<li class=\"li3\"><span class=\"s1\">Set the time to the desired target time zone.<\/span><\/li>\n<\/ol>\n<pre class=\"lang:default decode:true\">Calendar calendar = new GregorianCalendar();\ncalendar.setTimeZone(TimeZone.getTimeZone(\"America\/New_York\"));\nSystem.out.println(\"NYC: \" + calendar.get(Calendar.HOUR_OF_DAY));\nSystem.out.println(\"NYC: \" + calendar.getTimeInMillis());<\/pre>\n<p class=\"p6\"><span class=\"s1\">The output from this example would be: <\/span><\/p>\n<p class=\"p13\"><span class=\"s1\">NYC: 8<\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">NYC: 1363351520548<\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">The function, Calendar.getTimeInMillis(), always returns the time in UTC, regardless of the time zone set on the Calendar instance. The table below shows a list of time zone IDs that can be used with the TimeZone class:<\/span><\/p>\n<p><span class=\"s1\"><b>1.9. Messages<\/b><\/span><\/p>\n<p class=\"p3\"><span class=\"s1\">Messages help the user to understand the status of a program. Messages keep the user informed, and also display any errors that are occurring. Local applications need to display messages in the appropriate language to be understood by a user in a specific locale. As described previously, strings are usually moved into a ResourceBundle to be translated appropriately. However, if there is data embedded in a message that is variable, there are some extra steps to prepare it for <a href=\"https:\/\/phrase.com\/blog\/posts\/translation\/\">translation<\/a>.<\/span><\/p>\n<p class=\"p3\"><span class=\"s1\">A compound message contains data that has numbers or text that are local-specific. <\/span><\/p>\n<p><span class=\"s1\"><b>1.10. Character Methods<\/b><\/span><\/p>\n<p class=\"p6\"><span class=\"s5\">The <\/span><span class=\"s1\">java.lang.Character class has many methods that are useful for comparing characters, which is very useful in internationalization. The methods can tell if a character is a number, letter, space, or if it is upper or lower case, and they are based upon Unicode characters. Some of the most useful character methods are:<\/span><\/p>\n<ul>\n<li class=\"li6\"><span class=\"s1\">isDigit<\/span><\/li>\n<li class=\"li6\"><span class=\"s1\">isLetter<\/span><\/li>\n<li class=\"li6\"><span class=\"s1\">isLetterOrDigit<\/span><\/li>\n<li class=\"li6\"><span class=\"s1\">isLowerCase<\/span><\/li>\n<li class=\"li6\"><span class=\"s1\">isUpperCase<\/span><\/li>\n<li class=\"li6\"><span class=\"s1\">isSpaceChar<\/span><\/li>\n<li class=\"li6\"><span class=\"s1\">isDefined<\/span><\/li>\n<\/ul>\n<p class=\"p6\"><span class=\"s5\">The input parameter for each of these methods is a char. <\/span><span class=\"s1\">For example, if char newChar = \u2018A\u2019, then Character.isDigit (newChar) = False and Character.isLetter(newChar) = true.\u00a0<\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">The Character class also has a getType() method. The getType method returns the type of a specified character. For example, the getType method will return Character.UPPERCASE_LETTER for the character \u201cA\u201d. The Character API documentation fully specifies the methods in the Character class.<\/span><\/p>\n<p><span class=\"s1\"><b>1.11. Sorting Strings<\/b><\/span><\/p>\n<p class=\"p3\"><span class=\"s1\">Different languages may have different rules for the sequence and sorting of strings and letters. If your application is for an English-speaking audience, string comparisons can be performed with the String.compareTo method. The String.compareTo method performs a comparison of the Unicode characters within two strings. In many languages, the Unicode values do not correspond to the relative order of the characters, therefore, the String.compareTo method cannot be used. The java.text.Collator class allows use to perform string comparisons in different languages.To use the Collator class for a specific local, the following code can be used:<\/span><\/p>\n<pre class=\"lang:default decode:true\">Locale \u00a0 locale = Locale.US;\nCollator collator = Collator.getInstance(locale);<\/pre>\n<p class=\"p5\"><span class=\"s1\">The compare() method can be used to compare strings. The outputs of this method are a -1, 0, or 1. The \u201c-1\u201d output means that the first string occurs earlier than the second string. A \u201c0\u201d means that the strings have the same order, and a \u201c1\u201d means that the first strings occur later in the order. An example is as follows:<\/span><\/p>\n<pre class=\"lang:default decode:true\">Locale \u00a0 locale = Locale.US;\nCollator collator = Collator.getInstance(locale);\nint result = collator.compare(\"ab\", \"yz\");<\/pre>\n<p class=\"p5\"><span class=\"s1\">The return value would result in a \u201c-1\u201d. The string \u201cab\u201d will appear before the string \u201cyz\u201d when sorted according to the US rules.<\/span><\/p>\n<p><span class=\"s1\"><b>1.12. Customized Collation Rules<\/b><\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">If the pre-defined collation rules in the <\/span><span class=\"s5\">java.text.Collator class does not meet your needs, then you can define <\/span><span class=\"s1\">customer rules and assign them to a RuleBasedCollator object. The steps for doing this is as follows:<\/span><\/p>\n<ol class=\"ol1\">\n<li class=\"li5\"><span class=\"s1\">Define the rules that will be used to compare characters in a string object.<\/span><\/li>\n<li class=\"li5\"><span class=\"s1\">Pass the string to the RuleBasedCollator constructor<\/span><\/li>\n<li class=\"li5\"><span class=\"s1\">Use compare() method to compare the desired characters<\/span><\/li>\n<li class=\"li5\"><span class=\"s1\">Print the result<\/span><\/li>\n<\/ol>\n<p class=\"p6\"><span class=\"s1\">Here is an example: <\/span><\/p>\n<pre class=\"lang:default decode:true\">String usRules = \"&lt; x &lt; y &lt; z\";\nRuleBasedCollator usCollator = new RuleBasedCollator(usRules);\nint result = usCollator.compare(\"x\", \"z\");\nSystem.out.println(result);<\/pre>\n<p class=\"p6\"><span class=\"s1\">The example defines that x comes before y, and y comes before z. The results will print out a \u201c1\u201d because x comes before z. <\/span><\/p>\n<p><span class=\"s1\"><b>1.13. Detecting Text Boundaries<\/b><\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">Many applications need to find where text boundaries begin and end. In different languages, character, word, and sentence boundaries may abide by different rules. One method of handling this is to search for punctuation such as periods, commas, spaces, or colons. The java.text.BreakIterator class makes it easier to search for boundaries in different languages.<\/span><\/p>\n<p><span class=\"s1\"><b>1.13.1. Using the BreakIterator Class<\/b><\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">There are four types of boundaries that can be analyzed with the BreakIterator class: character, word, sentence, and line boundaries. The corresponding methods are:<\/span><\/p>\n<ul>\n<li class=\"li6\"><span class=\"s1\">getCharacterInstance<\/span><\/li>\n<li class=\"li6\"><span class=\"s1\">getWordInstance<\/span><\/li>\n<li class=\"li6\"><span class=\"s1\">getSentenceInstance<\/span><\/li>\n<li class=\"li6\"><span class=\"s1\">getLineInstance<\/span><\/li>\n<\/ul>\n<p class=\"p6\"><span class=\"s1\">These methods use the locale as the input parameter and then creates a BreakIterator instance. A new instance is required for each type of boundary. Here is a simple example: <\/span><\/p>\n<pre class=\"lang:default decode:true\">Locale locale = LocaleUK;\nBreakIterator breakIterator = BreakIterator.characterInstance(locale);<\/pre>\n<p class=\"p13\"><span class=\"s1\">The BreakIterator class holds an imaginary cursor to a current boundary in a string of text, and the cursor can be moved with the previous and next methods. The first boundary will be \u201c0\u201d, and the last boundary will be the length of the string.<\/span><\/p>\n<p class=\"p13\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1461 size-full\" src=\"https:\/\/phrase.com\/wp-content\/uploads\/2016\/09\/Im-loving-this-tutorial.png\" alt=\"boundaries found using the BreakIterator class | Phrase\" width=\"637\" height=\"173\" \/><\/p>\n<p class=\"p13\" style=\"text-align: center;\"><span class=\"s1\"><b>Figure 6. The boundaries found using the BreakIterator class.<\/b><\/span><\/p>\n<p><span class=\"s1\"><b>1.14. Character Boundaries<\/b><\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">Finding the location of character boundaries may be important if the end user can highlight one character at a time. Depending upon the language used, a character may depend on upon more than one Unicode character. The getCharacterInstance method in the BreakIterator class finds character boundaries for user characters, not Unicode characters. <\/span><\/p>\n<ol class=\"ol1\">\n<li class=\"li6\"><span class=\"s1\">Create BreakIterator instance.<\/span><\/li>\n<li class=\"li6\"><span class=\"s1\">The first method retrieves the first character boundary <\/span><\/li>\n<li class=\"li6\"><span class=\"s1\">The next method finds all breaks until the constant BreakIterator.DONE is returned<\/span><\/li>\n<\/ol>\n<p class=\"p6\"><span class=\"s1\">The following example finds character boundaries in US English using the text provided in the setText() method: <\/span><\/p>\n<pre class=\"lang:default decode:true\">Locale locale = Locale.US;\nBreakIterator breakIterator = BreakIterator.getCharacterInstance(locale);\nbreakIterator.setText(\"This tutorial is really great.\");\nint boundaryIndex = breakIterator.first();\nwhile(boundaryIndex != BreakIterator.DONE) {\n\u00a0 \u00a0 System.out.println(boundaryIndex) ;\n\u00a0 \u00a0 boundaryIndex = breakIterator.next();\n}<\/pre>\n<p><span class=\"s1\"><b>1.15. Word, Sentence and Line Boundaries<\/b><\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">A BreakIterator instance can be created for word, sentence, or line boundaries for a particular language. The methods for each of these boundaries are:<\/span><\/p>\n<ul>\n<li class=\"li6\"><span class=\"s1\">getWordIterator<\/span><\/li>\n<li class=\"li6\"><span class=\"s1\">getSentenceInstance<\/span><\/li>\n<li class=\"li6\"><span class=\"s1\">getLineInstance<\/span><\/li>\n<\/ul>\n<p class=\"p6\"><span class=\"s1\">An example of the getWordIterator() for finding boundaries in the US English text is as follows:<\/span><\/p>\n<pre class=\"lang:default decode:true\">Locale locale = Locale.US;\nBreakIterator breakIterator = BreakIterator.getWordInstance(locale);\nbreakIterator.setText(\"This tutorial is really great.\");\nint boundaryIndex = breakIterator.first();\nwhile(boundaryIndex != BreakIterator.DONE) {\n\u00a0 \u00a0 System.out.println(boundaryIndex) ;\n\u00a0 \u00a0 boundaryIndex = breakIterator.next();\n}<\/pre>\n<p class=\"p6\"><span class=\"s1\">As shown previously, the first() and next() methods return the Unicode index of the found word boundary. The boundaries would be marked as follows:<\/span><\/p>\n<p class=\"p6\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1472 size-full\" src=\"https:\/\/phrase.com\/wp-content\/uploads\/2016\/09\/This-tutorial-is-really-great.png\" alt=\"boundaries found using the first() and next() methods | Phrase\" width=\"790\" height=\"105\" \/><\/p>\n<p class=\"p6\" style=\"text-align: center;\"><span class=\"s1\"><b>Figure 7. The boundaries found using the <\/b><\/span><span class=\"s7\"><b>first()<\/b><\/span><span class=\"s1\"><b> and <\/b><\/span><span class=\"s7\"><b>next()<\/b><\/span><span class=\"s1\"><b> methods.<\/b><\/span><\/p>\n<p><span class=\"s1\"><b>1.16. Converting to and from Unicode<\/b><\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">Unicode characters should be used in internationalization of all software, operating systems, and the world wide web. The Java programming language stores all characters in UTF-16. Since not all text received from users default file encoding, your application may need to convert into Unicode. Outgoing text may also need to be converted from Unicode to the format required by the outside file. <\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">Java uses two main methods to convert text to Unicode:<\/span><\/p>\n<ul>\n<li class=\"li5\"><span class=\"s3\">String<\/span><span class=\"s1\"> class<\/span><\/li>\n<li class=\"li5\"><span class=\"s3\">Reader<\/span><span class=\"s1\"> and <\/span><span class=\"s3\">Writer<\/span><span class=\"s1\"> classes <\/span><\/li>\n<\/ul>\n<p><span class=\"s1\"><b>1.16.1 String Class<\/b><\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">The Sting class can be used to convert a byte array to a String instance.<span class=\"Apple-converted-space\">\u00a0 <\/span>The string class can be used by first creating a byte array. The byte array and specific byte encoding to convert are used as parameters to the constructor to create a new string. The String constructor then converts the bytes from the character set of the byte array to Unicode. An example of using the Sting class to convert a byte array to a <\/span><span class=\"s7\">String<\/span><span class=\"s1\"> instance is as follows:<\/span><\/p>\n<pre class=\"lang:default decode:true\">byte[] bytesArray = new byte[10]; \/\/ array of bytes (0xF0, 0x9F, 0x98, 0x81)\nString string = new String(bytesArray, Charset.forName(\"UTF-8\")); \/\/ covert\nbyteArraySystem.out.println(string); \/\/ Test result<\/pre>\n<p class=\"p6\"><span class=\"s1\">A string can also be converted to another format using the getBytes() method. This example uses the string \u201chello\u201d:<\/span><\/p>\n<pre class=\"lang:default decode:true\">String Str1 = new String(\"hello\");\nStr2 = Str1.getBytes( \"UTF-8\" );\nSystem.out.println(Str2);<\/pre>\n<p><span class=\"s1\"><b>1.16.2. Reader<\/b><\/span><span class=\"s3\"><b> and <\/b><\/span><span class=\"s1\"><b>Writer<\/b><\/span><b> <\/b><span class=\"s1\"><b>Classes<\/b><\/span><b> <\/b><\/p>\n<p class=\"p6\"><span class=\"s1\">The Java.io package Reader and Writer Classes enable a Java application to convert between Unicode character streams and byte stream of non-Unicode text. The InputStreamReader class <\/span><span class=\"s7\">converts <\/span><span class=\"s1\">from a certain character set (UTF-8) to Unicode. The OutputStreamWriter can translate Unicode to non-Unicode characters. The following example demonstrates how to translate a text file in the UTF-8 encoding into Unicode:<\/span><\/p>\n<pre class=\"lang:default decode:true\">FileInputStream inputStream = new FileInputStream(\"test.txt\");\nInputStreamReader reader = new InputStreamReader(inputStream, \"UTF8\");<\/pre>\n<p class=\"p6\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1465 size-full\" src=\"https:\/\/phrase.com\/wp-content\/uploads\/2016\/09\/image-3.png\" alt=\"Illustration of InputStreamReader and OutputStreamWriter | Phrase\" width=\"929\" height=\"275\" \/><\/p>\n<p class=\"p6\" style=\"text-align: center;\"><span class=\"s1\"><b>Figure 8. Illustration of <\/b><\/span><span class=\"s7\"><b>InputStreamReader and <\/b><\/span><span class=\"s1\"><b>OutputStreamWriter.<\/b><\/span><\/p>\n<p class=\"p3\"><span class=\"s1\">This example creates a FileInputStream and puts it in an InputStreamReader. To write a stream of characters back into UTF-8 encoding from Unicode, the following can be used:<\/span><\/p>\n<pre class=\"lang:default decode:true\">OutputStream outputStream = new FileOutputStream(\"output.txt\");\nOutputStreamWriter \u00a0 writer\u00a0 = new OutputStreamWriter(outputStream, \u201cUTF-8\");<\/pre>\n<p class=\"p6\"><span class=\"s1\">These classes will reply on the default encoding it the encoding identifier is not specified. The getEncoding method can be used with the InputStreamReader or OutputStreamWriter as follows:<\/span><\/p>\n<pre class=\"lang:default decode:true\">InputStreamReader defaultReader = new InputStreamReader(inputStream);\nString defaultEncoding = defaultReader.getEncoding();<\/pre>\n<h2><span class=\"ez-toc-section\" id=\"an-example-program-before-and-after-internationalization\"><\/span>An Example Program: Before and After Internationalization<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p><span class=\"s1\"><b>1. Before Internationalization<\/b><\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">Most programs that are written in one particular language and locale (in our case English), and have text hard-coded into the program code. As an example, you have written the following program entitled \u201cNotInternationalized\u201d:<\/span><\/p>\n<pre class=\"lang:default decode:true\">public class NotInternationalized {\n\u00a0 \u00a0 static public void main(String[] args) {\n\u00a0 \u00a0 \u00a0 \u00a0 System.out.println(\"Hello.\");\n\u00a0 \u00a0 }\n}<\/pre>\n<p class=\"p29\"><span class=\"s1\">You would like this program to display the same messages for users in Germany and France. Since you do not know German and French, you will need to hire a <a href=\"https:\/\/phrase.com\/blog\/posts\/a-day-in-the-life-of-a-translator\/\">translator<\/a>, and since the translator will not be used to looking at the code, and the text that needs to be translated needs to be moved into a separate file. Also, you are interested in translating this program into other languages in the future. The best method of efficiently translating these messages is to internationalize the program.<\/span><\/p>\n<p><span class=\"s1\"><b>2. After Internationalization<\/b><\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">The program after internationalization looks like the following example. The messages are not hardcoded into the program.<\/span><\/p>\n<pre class=\"lang:java decode:true\">import java.util.*;\npublic class InternationalizedSample {\n\u00a0 \u00a0 static public void main(String[] args) {\n\u00a0 \u00a0 \u00a0 \u00a0 String language;\n\u00a0 \u00a0 \u00a0 \u00a0 String country;\n\u00a0 \u00a0 \u00a0 \u00a0 if (args.length != 2) {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 language = new String(\"en\");\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 country = new String(\"US\");\n\u00a0 \u00a0 \u00a0 \u00a0 } else {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 language = new String(args[0]);\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 country = new String(args[1]);\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\u00a0 \u00a0 \u00a0 \u00a0 Locale currentLocale;\n\u00a0 \u00a0 \u00a0 \u00a0 ResourceBundle messages;\n\u00a0 \u00a0 \u00a0 \u00a0 currentLocale = new Locale(language, country);\n\u00a0 \u00a0 \u00a0 \u00a0 messages = ResourceBundle.getBundle(\"MessagesBundle\", currentLocale);\n\u00a0 \u00a0 \u00a0 \u00a0 System.out.println(messages.getString(\"greetings\"));\n\u00a0 \u00a0 }\n}<\/pre>\n<h2><span class=\"ez-toc-section\" id=\"java-internationalizing-the-sample-program\"><\/span>Java Internationalizing the Sample Program<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p class=\"p6\"><span class=\"s1\">As you can see, the internationalized source code has the hardcoded messages removed. The language is specified at run time, therefore, the program can be distributed worldwide. The steps for creating the internationalized program is as follows:<\/span><\/p>\n<p class=\"p6\"><span class=\"s1\"><b>1. Create the Properties Files<\/b><\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">A properties file stores the text that needs to be translated. The properties file is in plain-text format, and can be created using any text editor. We will name the properties file MessagesBundle.properties, and it has the following text:<\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">greetings = Hello<\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">We will create a new properties file for every language that we would like the text translated to. For the French text, we will create the MessagesBundle_fr_FR.properties file. MessagesBundle_fr_FR.properties file contains the fr language code and the FR country code, and contains these lines:<\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">greetings = Bonjour.<\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">The values on the left sign of the equal sign are called \u201ckeys\u201d, and these remain the same in every properties file. These are the references that the globalized program uses to call the values in a particular language.<\/span><\/p>\n<p class=\"p6\"><span class=\"s1\"><b>2. Define the Locale<\/b><\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">A Locale object specified a particular region and language. A Locale for the English language and the United States is as follows:<\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">aLocale = new Locale(&#8220;en&#8221;,&#8221;US&#8221;);<\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">To create Locale objects for the French language in Canada and France, we have the following:<\/span><\/p>\n<p class=\"p13\"><span class=\"s1\">caLocale = new Locale(&#8220;fr&#8221;,&#8221;CA&#8221;);<\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">frLocale = new Locale(&#8220;fr&#8221;,&#8221;FR&#8221;);<\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">The internationalized program gets the hardcoded language and country codes from the command line at run time:<\/span><\/p>\n<p class=\"p13\"><span class=\"s1\">String language = new String(args[0]);<\/span><\/p>\n<p class=\"p13\"><span class=\"s1\">String country = new String(args[1]);<\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">currentLocale = new Locale(language, country);<\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">Specifying a local only identifies a region and language. For other functions, additional code must be written to format dates, numbers, currencies, time zones, etc. These objects are <i>locale-sensitive<\/i> because their behavior varies according to Locale. A ResourceBundle is an example of a locale-sensitive object.<\/span><\/p>\n<p class=\"p6\"><span class=\"s1\"><b>3. Create a ResourceBundle<\/b><\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">A ResourceBundle contains locale-specific objects like translatable text. The ResourceBundle uses properties files that contain the text to be displayed. The ResourceBundle is created as follows:<\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">messages = ResourceBundle.getBundle(&#8220;MessagesBundle&#8221;, currentLocale);<\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">There are two inputs to the getBundle method: the properties file and the locale. &#8220;MessagesBundle&#8221; refers to the family of properties files:<\/span><\/p>\n<p class=\"p13\"><span class=\"s1\">MessagesBundle_en_US.properties<\/span><\/p>\n<p class=\"p13\"><span class=\"s1\">MessagesBundle_fr_FR.properties<\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">MessagesBundle_de_DE.properties<\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">The locale will specify which MessagesBundle files is chosen using the language and country code, which follows the MessagesBundle in the names of the properties files. The next step is to obtain the translated messages from the ResourceBundle.<\/span><\/p>\n<p class=\"p6\"><span class=\"s1\"><b>4. Fetch the Text from the ResourceBundle<\/b><\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">To retrieve the message from the ResourceBundle, the getString method is used. The keys are hardcoded into the code, and the keys fetch the values which are the translated messages. An example of the getString method is as follows:<\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">String msg1 = messages.getString(&#8220;greetings&#8221;);<\/span><\/p>\n<h2><span class=\"ez-toc-section\" id=\"translating-java-applications%e2%80%94the-easy-way\"><\/span>Translating Java Applications\u2014the Easy Way<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p class=\"p6\"><span class=\"s1\">The basic steps of internationalizing a Java application are fairly simple. The process requires some planning and some extra coding, but the process of internationalization can save a lot of time if the program needs to be used in multiple locales. The steps and examples discussed in this tutorial provide a starting point for some of the key internationalization features of the Java programming language. <\/span><\/p>\n<p class=\"p6\"><span class=\"s1\">As soon as you&#8217;re ready to move on with the translation of your app copy, consider using a dedicated software localization platform like <a href=\"https:\/\/phrase.com\/platform\/strings\/\">Phrase Strings<\/a>. As part of the Phrase Localization Platform, Phrase Strings can help you manage your software localization projects while being fully integrated with your existing tech stack. Its beautiful translation editor allows you to edit and control localization files directly in your browser. It also comes with an in-context editor that provides translators with useful contextual information to improve overall translation quality. The platforms and formats that Phrase supports include Java, Ruby, PHP, Python, javascript, as well as many more.<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>With over 100 locales supported, Java offers many features for streamlined Java localization and internationalization. Here&#8217;s a starting point.<\/p>\n","protected":false},"author":61,"featured_media":2612,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_stopmodifiedupdate":true,"_modified_date":"","_searchwp_excluded":"","footnotes":""},"categories":[40],"class_list":["post-8655","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-software-localization"],"acf":[],"_links":{"self":[{"href":"https:\/\/phrase.com\/wp-json\/wp\/v2\/posts\/8655"}],"collection":[{"href":"https:\/\/phrase.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/phrase.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/phrase.com\/wp-json\/wp\/v2\/users\/61"}],"replies":[{"embeddable":true,"href":"https:\/\/phrase.com\/wp-json\/wp\/v2\/comments?post=8655"}],"version-history":[{"count":5,"href":"https:\/\/phrase.com\/wp-json\/wp\/v2\/posts\/8655\/revisions"}],"predecessor-version":[{"id":89418,"href":"https:\/\/phrase.com\/wp-json\/wp\/v2\/posts\/8655\/revisions\/89418"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/phrase.com\/wp-json\/wp\/v2\/media\/2612"}],"wp:attachment":[{"href":"https:\/\/phrase.com\/wp-json\/wp\/v2\/media?parent=8655"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/phrase.com\/wp-json\/wp\/v2\/categories?post=8655"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}