CS 596 Java Programming Fall Semester, 1998 Internationalization |
||
---|---|---|
© 1998, All Rights Reserved, SDSU & Roger Whitney San Diego State University -- This page last updated 21-Dec-98 |
Internationalization
Formatting
Are dates formatted as:
Java's Solution
An instances of the java.util.Locale class contains the rules for a language in a location
Each Java virtual machine has a default instance of the Locale class, which should be for the local language rules in the current country
java.text.NumberFormat
Formats numbers, currency, and percents using the default Locale rules
For finer control over formatting numbers use java.text.DecimalFormat
java.text.DateFormat
Formats dates and time using the default Locale rules
Dates and times can be formatted in FULL, LONG, MEDIUM, and SHORT versions
For finer control over formatting dates use java.text.SimpleDateFormat
java.util.Locale
You create a Locale object using one of the two constructors of this class:
Languages and Countries Available in JDK1.2RC1
Country Code Language Code Albania AL Albanian sq Algeria DZ Arabic ar Argentina AR Spanish es Australia AU English en Austria AT German de Bahrain BH Arabic ar Belarus BY Byelorussian be Belgium BE Dutch nl Belgium BE French fr Bolivia BO Spanish es Brazil BR Portuguese pt Bulgaria BG Bulgarian bg Canada CA English en Canada CA French fr Chile CL Spanish es China CN Chinese zh Colombia CO Spanish es Costa Rica CR Spanish es Croatia HR Croatian hr Czech Republic CZ Czech cs Denmark DK Danish da Dominican Republic DO Spanish es Ecuador EC Spanish es Egypt EG Arabic ar El Salvador SV Spanish es Estonia EE Estonian et Finland FI Finnish fi France FR French fr Germany DE German de Greece GR Greek el Guatemala GT Spanish es Honduras HN Spanish es Hong Kong HK Chinese zh Hungary HU Hungarian hu Iceland IS Icelandic is Iraq IQ Arabic ar
Country Code Language Code Ireland IE English en Israel IL Hebrew iw Italy IT Italian it Italy IT Italian it Japan JP Japanese ja Jordan JO Arabic ar Kuwait KW Arabic ar Latvia LV Latvian (Lettish) lv Lebanon LB Arabic ar Libya LY Arabic ar Lithuania LT Lithuanian lt Luxembourg LU French fr Luxembourg LU German de Macedonia MK Macedonian mk Mexico MX Spanish es Morocco MA Arabic ar Netherlands NL Dutch nl New Zealand NZ English en Nicaragua NI Spanish es Norway NO Norwegian no Oman OM Arabic ar Panama PA Spanish es Paraguay PY Spanish es Peru PE Spanish es Poland PL Polish pl Portugal PT Portuguese pt Puerto Rico PR Spanish es Qatar QA Arabic ar Romania RO Romanian ro Russia RU Russian ru Saudi Arabia SA Arabic ar Slovakia SK Slovak sk Slovenia SI Slovenian sl South Africa ZA English en South Korea KR Korean ko
Country Code Language Code Spain ES Catalan ca Spain ES Spanish es Sudan SD Arabic ar Sweden SE Swedish sv Switzerland CH French fr Switzerland CH German de Switzerland CH Italian it Syria SY Arabic ar Taiwan TW Chinese zh Thailand TH Thai th Tunisia TN Arabic ar Turkey TR Turkish tr Ukraine UA Ukrainian uk United Arab Emirates AE Arabic ar United Kingdom GB English en United States US English en Uruguay UY Spanish es Venezuela VE Spanish es Yemen YE Arabic ar Yugoslavia YU Serbian sr Yugoslavia YU Serbo-Croatian sh
Using the Default Locale to Format import java.text.*; class FormatUsingLocalRules { public static void main( String args[] ) throws Exception { NumberFormat number = NumberFormat.getInstance( ); NumberFormat currency = NumberFormat.getCurrencyInstance( ); DateFormat shortDate = DateFormat.getDateInstance(DateFormat.SHORT); DateFormat fullTime = DateFormat.getTimeInstance(DateFormat.FULL ); System.out.println( "Number: " + number.format( 123456 )); System.out.println( "Currency: " + currency.format( 1234.56 )); System.out.println( "ShortDate: " + shortDate.format( new Date() )); System.out.println( "FullTime: " + fullTime.format( new Date() )); } }Output Number: 123,456
Currency: $1,234.56
ShortDate: 10/13/97
FullTime: 5:15:42 oclock PM PDT
International Example
Explicitly use other locales to show that they are different
Usually you do not want to use locales explicitly, usually:
class FormatExplicitlyCallingDifferentLocale { public static void main( String args[] ) { System.out.println( "-------US English------"); internationalPrint( Locale.getDefault() ); System.out.println( "-------Canadian English------"); internationalPrint( new Locale("en", "CA" )); System.out.println( "-------Spanish Spanish------"); internationalPrint( new Locale("es", "ES" )); System.out.println( "-------German German------"); internationalPrint( new Locale("de", "DE" )); } //internationalPrint on next slide
//International Example - continued
public static void internationalPrint( Locale custom ) { NumberFormat number = NumberFormat.getInstance( custom ); NumberFormat currency = NumberFormat.getCurrencyInstance( custom ); DateFormat shortDate = DateFormat.getDateInstance( DateFormat.SHORT, custom ); DateFormat fullDate = DateFormat.getDateInstance( DateFormat.FULL, custom ); DateFormat shortTime = DateFormat.getTimeInstance( DateFormat.SHORT, custom ); DateFormat longTime = DateFormat.getTimeInstance( DateFormat.LONG,custom ); System.out.println( "Number: " + number.format( 123456 )); System.out.println( "Currency: " + currency.format( 1234.56 )); System.out.println( "ShortDate: " + shortDate.format( new Date() )); System.out.println( "FullDate: " + fullDate.format( new Date() )); System.out.println( "ShortTime: " + shortTime.format( new Date() )); System.out.println( "LongTime: " + longTime.format( new Date() )); } }
//International Example - continued
Output -------US English------
Number: 123,456
Currency: $1,234.56
ShortDate: 10/12/97
FullDate: Sunday, October 12, 1997
ShortTime: 9:45 PM
LongTime: 9:45:46 PM PDT
-------Canadian English------
Number: 123;456
Currency: $1;234.56
ShortDate: 12/10/97
FullDate: Sunday, October 12, 1997
ShortTime: 9:45 PM
LongTime: 9:45:46 PDT PM
-------Spanish Spanish------
Number: 123.456
Currency: 1.234,56 Pts
ShortDate: 13/10/97
FullDate: lunes 13 de octubre de 1997
ShortTime: 6:45
LongTime: 6:45:46 GMT+02:00
-------German German------
Number: 123.456
Currency: 1.234,56 DM
ShortDate: 13.10.97
FullDate: Montag, 13. Oktober 1997
ShortTime: 06:45
LongTime: 06:45:46 GMT+02:00
Parsing Numbers/Dates Etc.
import java.text.*; import java.util.Locale; public class Test { public static void main( String args[] ) throws Exception { Locale Spain = new Locale("es", "ES" ); NumberFormat spanishFormat = NumberFormat.getInstance( Spain ); Number parsed = spanishFormat.parse( "123.456,5"); System.out.println( parsed.floatValue() ); parsed = spanishFormat.parse( "123.4.5.6,5"); System.out.println( parsed.floatValue() ); } }Output 123456.5
123456.5
Static and Dynamic Text
import java.text.MessageFormat; import java.util.Date; class Test { public static void main( String args[] ) throws Exception { Object[] dynamicText = {"Roger",new Date() }; String staticText = "{0}, it is {1,time,short}"; String publicMessage = MessageFormat.format(staticText, dynamicText); System.out.println( publicMessage ); } }Output Roger, it is 10:03 PM
Internationalization of Text
In Java, you can write programs that will display text in the native language of the country in which the program is being run
The programmer has to supply the translations into each language
At run time the program will select the proper language, assuming the program uses correctly the internationalization features of the JDK
The translations of the text can be placed in data files or in special classes
Hello World Example with Just Classes
import java.util.ResourceBundle; // The main program, will display either German, Spanish // or English depending on where you run the program class HelloWorld { public static void main( String args[] ) { ResourceBundle greetings = ResourceBundle.getBundle( "Greetings" ); System.out.println( greetings.getString( "hello" )); } } // The default language, if the local language and/or country // can not be found this one will be used import java.util.ListResourceBundle; public class Greetings extends ListResourceBundle { public Object[][] getContents() { return new Object[][] { { "hello", "Hello World!" }, { "language", "English" }, { "key", "value" } // can have as many pairs as needed }; } }
//Hello World - Continued // Append _language code to base class name for a language // Append _language_country to base class to indicate both // langauge and country // de = 2 letter ISO-639 code for German public class Greetings_de extends ListResourceBundle { public Object[][] getContents() { return new Object[][] { { "hello", "Hallo, Welt!" }, { "language", "Deutsch" } }; } } // de = 2 letter ISO-639 code for Spanish public class Greetings_es extends ListResourceBundle { public Object[][] getContents() { return new Object[][] { { "hello", "\u00A1Hola mundo!" }, { "language", "Espa\u00F1ol" } }; } } // \u00A1 = inverted ! \u00BF = inverted ? // \u00D1 = N with a tilde \u00F1 = n with a tilde
Hello World Tested
import java.util.Locale; import java.util.ResourceBundle; class ThreeHellos { public static void main( String args[] ) { foreignTest( ); Locale.setDefault( new Locale("es", "ES" )); foreignTest(); Locale.setDefault( new Locale("de", "DE" )); foreignTest( ); } public static void foreignTest( ) { ResourceBundle greetings = ResourceBundle.getBundle( "Greetings"); System.out.println( "----" + greetings.getString( "language") + "----"); System.out.println( greetings.getString( "hello" )); } }Output ----English----
Hello World!
----Español----
¡Hola mundo!
----Deutsch----
Hallo, Welt!
Warning about Class Structure
Here are two ways to structure the Greetings class. The first was used just to save room on the slide (I print these out on 8.5 by 11 paper using 18-point font size). The first creates the array each time the method getContents is called (unless the compiler optimizes the call). The second only creates the array once, hence should be more efficient. I do not have any data to indicate what impact this would have on a program.
public class Greetings extends ListResourceBundle { public Object[][] getContents() { return new Object[][] { { "hello", "Hello World!" }, { "language", "English" }, }; } }
public class Greetings extends ListResourceBundle { static final Object[][] contents = { { "hello", "Hello World!" }, { "language", "English" }, { "key", "value" } // can have as many pairs as needed }; public Object[][] getContents() { return contents; } }
Hello World Example - Using Files
Replace the classes Greetings, Greetings_de, Greetings_es with the following files below
Then either ThreeHellos or HelloWorld will work the same
In file Greetings.properties hello = Hello World!
language = English
In file Greetings_es.properties hello = \u00A1Hola mundo!
language = Espa\u00F1ol
# \u00A1 = Unicode for inverted "!"
# \u00F1 = Unicode for n with tilde
In Greetings_de.properties hello = Hallo, Welt!
language = Deutsch
A More Complex Example
In file Greetings.properties hello = Hello World!
language = English
publicService = {0}, it is {1,time,short}, do you know where your children are?
In file Greetings_es.properties hello = \u00A1Hola mundo!
language = Espa\u00F1ol
publicService = {0}, son las {1,time,short} -- \u00BFsabes donde estan tus hijos?
# \u00A1 = inverted ! # \u00BF = inverted ? # \u00F1 = n with a tilde
In Greetings_de.properties hello = Hallo, Welt!
language = Deutsch
publicService = {0}, es ist {1,time,short}. Weisst Du, wo Deine Kinder sind?
Testing the Different Locales
import java.text.MessageFormat; import java.util.Date; import java.util.Locale; import java.util.ResourceBundle; import java.util.ListResourceBundle; class HelloWithPublicService { static Object[] dynamicData = { System.getProperty( "user.name" ), new Date() }; public static void main( String args[] ) { foreignTest( ); Locale.setDefault( new Locale("es", "ES" )); foreignTest(); Locale.setDefault( new Locale("de", "DE" )); foreignTest( ); }
// HelloWithPublicService - Continued public static void foreignTest( ) { ResourceBundle greetings = ResourceBundle.getBundle( "Greetings"); MessageFormat publicMessage; publicMessage = new MessageFormat( greetings.getString( "publicService")); System.out.println( "----" + greetings.getString( "language") + "----"); System.out.println( greetings.getString( "hello" )); System.out.println( publicMessage.format( dynamicData )); } }Output ----English---- Hello World! Roger Whitney, it is 10:11 PM, do you know where your children are? ----Español---- ¡Hola mundo! Roger Whitney, son las 6:11 -- ¿sabes donde estan tus hijos? ----Deutsch---- Hallo, Welt! Roger Whitney, es ist 06:11. Weisst Du, wo Deine Kinder sind?
Copyright © 1998 SDSU & Roger Whitney, 5500 Campanile Drive, San Diego, CA 92182-7700 USA.
All rights reserved.
visitors since 02-Dec-98