Java and Locales

Hideyuki Inada, Capitola Computing Inc.

Each country in the world has its own cultural conventions.  Sometimes, a country has multiple cultural conventions if it consists of more than one ethnic group.

When you internationalize your software, you have to take these issues into consideration.  Locale is used to refer to cultural conventions used in each country. If the format of data is affected by the locale, the data is said to be locale-sensitive. If the data is locale-sensitive, you have to present or process the data following the conventions used in the specific locale.

Typical locale-sensitive data are:

l         Date and time format

l         Number format including monetary format

l         Collation sequence

l         Name format

l         Address format

l         Unit of measurement - Metric (SI) or pound/feet

 

For date, time, number formats and collation sequence, Java provides string support of locale via the Locale class and various locale-sensitive formatter class.

Locale class

Before we discuss locale-sensitive data, let's go over the Locale class that  is essential in handling the locale-sensitive data in your code.  Here is how to instantiate the class for the major Western Europe and North America countries:

 

import java.util.*;

 

public class intl31 {

 

  public static void main(String args[])

  {

    String asLanguageCountry[][] = {

       // Western Europe

      { "en", "GB"},

      { "fr", "FR"},

      { "de", "DE"},

      { "es", "ES"},

      { "it", "IT"},

      { "sv", "SE"},

      { "da", "DK"},

      { "nl", "NL"},

 

       // North America

      { "en", "US"},

      { "en", "CA"},

      { "fr", "CA"},

      { "es", "MX"}

    };

    Locale l;

    int i;

 

    // Code

    for(i = 0; i < asLanguageCountry.length; i++){

      l = new Locale(asLanguageCountry[i][0], asLanguageCountry[i][1]);

      System.out.print(l.getDisplayName(Locale.US) + "\n");

    }

  }

intl31.java

In the first argument of the Locale constructor, you specify the two-digit ISO-639 language code in lower case.

In the second argument of the Locale constructor, you specify the two-digit ISO-3166 country code in upper case.

 

For example, since Canada has an English-speaking region and a French-speaking region, it has two locales to support each of them.

 

This code outputs the following:

C:\programs\javatest\site>java intl31

English (United Kingdom)

French (France)

German (Germany)

Spanish (Spain)

Italian (Italy)

Swedish (Sweden)

Danish (Denmark)

Dutch (Netherlands)

English (United States)

English (Canada)

French (Canada)

Spanish (Mexico)

 

In the sections that follow, we will use this code as the basis, and examine the formats for various locale-sensitive data.

Date and time format

Java provides the DateFormat class to present the date in a format appropriate for each locale.  The following code displays the current date for the countries we used in previous example in the four formats (full, long, medium and short formats):

 

import java.util.*;

import java.text.*;

 

public class intl33 {

 

  public static void main(String args[])

  {

    String asLanguageCountry[][] = {

       // Western Europe

      { "en", "GB"},

      { "fr", "FR"},

      { "de", "DE"},

      { "es", "ES"},

      { "it", "IT"},

      { "sv", "SE"},

      { "da", "DK"},

      { "nl", "NL"},

 

       // North America

      { "en", "US"},

      { "en", "CA"},

      { "fr", "CA"},

      { "es", "MX"}

    };

    Locale l;

    int i, j;

    DateFormat df;

    int aiDateFormat[] = {

      DateFormat.FULL,

      DateFormat.LONG,

      DateFormat.MEDIUM,

      DateFormat.SHORT

    };

 

    // Code

    for(j = 0; j < aiDateFormat.length; j++){

      for(i = 0; i < asLanguageCountry.length; i++){

        l = new Locale(asLanguageCountry[i][0], asLanguageCountry[i][1]);

        System.out.print(l.getDisplayName(Locale.US) + "\t");

 

        df = DateFormat.getDateInstance(aiDateFormat[j], l);

        System.out.print(df.format(new Date()) + "\n");

      }

    }

  }

}

intl33.java

The output result is following  (The chcp command issued at the beginning is to set the code page to 1252 on the machine that executes this program):

C:\programs\javatest\site>chcp 1252

Active code page: 1252

 

C:\programs\javatest\site>java intl33

English (United Kingdom)        04 October 2002

French (France) vendredi 4 octobre 2002

German (Germany)        Freitag, 4. Oktober 2002

Spanish (Spain) viernes 4 de octubre de 2002

Italian (Italy) venerdì 4 ottobre 2002

Swedish (Sweden)        den 4 oktober 2002

Danish (Denmark)        4. oktober 2002

Dutch (Netherlands)     vrijdag 4 oktober 2002

English (United States) Friday, October 4, 2002

English (Canada)        Friday, October 4, 2002

French (Canada) vendredi 4 octobre 2002

Spanish (Mexico)        viernes 4 de octubre de 2002

English (United Kingdom)        04 October 2002

French (France) 4 octobre 2002

German (Germany)        4. Oktober 2002

Spanish (Spain) 4 de octubre de 2002

Italian (Italy) 4 ottobre 2002

Swedish (Sweden)        den 4 oktober 2002

Danish (Denmark)        4. oktober 2002

Dutch (Netherlands)     4 oktober 2002

English (United States) October 4, 2002

English (Canada)        October 4, 2002

French (Canada) 4 octobre 2002

Spanish (Mexico)        4 de octubre de 2002

English (United Kingdom)        04-Oct-02

French (France) 4 oct. 02

German (Germany)        04.10.2002

Spanish (Spain) 04-oct-02

Italian (Italy) 4-ott-02

Swedish (Sweden)        2002-okt-04

Danish (Denmark)        04-10-2002

Dutch (Netherlands)     4-okt-02

English (United States) Oct 4, 2002

English (Canada)        4-Oct-02

French (Canada) 02-10-04

Spanish (Mexico)        4/10/2002

English (United Kingdom)        04/10/02

French (France) 04/10/02

German (Germany)        04.10.02

Spanish (Spain) 4/10/02

Italian (Italy) 04/10/02

Swedish (Sweden)        2002-10-04

Danish (Denmark)        04-10-02

Dutch (Netherlands)     4-10-02

English (United States) 10/4/02

English (Canada)        04/10/02

French (Canada) 02-10-04

Spanish (Mexico)        4/10/02

 

As you can see, the Month/Day/Year format that is used in the U.S. is not necessarily used in the rest of the world, and supporting different formats on your own requires certain development cycles.  Using the DateFormat class can take the burden off your development, and makes it possible to easily provide the international date format support in your software.

 

Time format

The appropriate time format for each locale can be obtained by calling DateFormat.getTimeInstance(). The following code contains a slight modification from the previous example to illustrate this:

 

import java.util.*;

import java.text.*;

 

public class intl34 {

 

  public static void main(String args[])

  {

    String asLanguageCountry[][] = {

       // Western Europe

      { "en", "GB"},

      { "fr", "FR"},

      { "de", "DE"},

      { "es", "ES"},

      { "it", "IT"},

      { "sv", "SE"},

      { "da", "DK"},

      { "nl", "NL"},

 

       // North America

      { "en", "US"},

      { "en", "CA"},

      { "fr", "CA"},

      { "es", "MX"}

    };

    Locale l;

    int i, j;

    DateFormat tf;

    int aiDateFormat[] = {

      DateFormat.FULL,

      DateFormat.LONG,

      DateFormat.MEDIUM,

      DateFormat.SHORT

    };

 

    // Code

    for(j = 0; j < aiDateFormat.length; j++){

      for(i = 0; i < asLanguageCountry.length; i++){

        l = new Locale(asLanguageCountry[i][0], asLanguageCountry[i][1]);

        System.out.print(l.getDisplayName(Locale.US) + "\t");

 

        tf = DateFormat.getTimeInstance(aiDateFormat[j], l);

        System.out.print(tf.format(new Date()) + "\n");

      }

      System.out.println("\n");

    }

  }

}

 

The output is shown below:

C:\programs\javatest\site>java intl34

English (United Kingdom)        17:54:06 o'clock PDT

French (France) 17 h 54 PDT

German (Germany)        17.54 Uhr PDT

Spanish (Spain) 17H54' PDT

Italian (Italy) 17.54.06 PDT

Swedish (Sweden)        kl 17:54 PDT

Danish (Denmark)        17:54:06 PDT

Dutch (Netherlands)     17:54:06 uur PDT

English (United States) 5:54:06 PM PDT

English (Canada)        5:54:06 o'clock PM PDT

French (Canada) 17 h 54 PDT

Spanish (Mexico)        05:54:06 PM PDT

 

 

English (United Kingdom)        17:54:06 PDT

French (France) 17:54:06 PDT

German (Germany)        17:54:06 PDT

Spanish (Spain) 17:54:06 PDT

Italian (Italy) 17.54.06 PDT

Swedish (Sweden)        17:54:06 PDT

Danish (Denmark)        17:54:06 PDT

Dutch (Netherlands)     17:54:06 PDT

English (United States) 5:54:06 PM PDT

English (Canada)        5:54:06 PDT PM

French (Canada) 17:54:06 PDT

Spanish (Mexico)        05:54:06 PM PDT

 

 

English (United Kingdom)        17:54:06

French (France) 17:54:06

German (Germany)        17:54:06

Spanish (Spain) 17:54:06

Italian (Italy) 17.54.06

Swedish (Sweden)        17:54:06

Danish (Denmark)        17:54:06

Dutch (Netherlands)     17:54:06

English (United States) 5:54:06 PM

English (Canada)        5:54:06 PM

French (Canada) 17:54:06

Spanish (Mexico)        05:54:06 PM

 

 

English (United Kingdom)        17:54

French (France) 17:54

German (Germany)        17:54

Spanish (Spain) 17:54

Italian (Italy) 17.54

Swedish (Sweden)        17:54

Danish (Denmark)        17:54

Dutch (Netherlands)     17:54

English (United States) 5:54 PM

English (Canada)        5:54 PM

French (Canada) 17:54

Spanish (Mexico)        05:54 PM

 

In addition to the time format, if your software supports simultaneous use of your software by multiple users in different time zones (for example U.S., Japan and Europe) at the same time, you may want to consider storing date/time information in a single time-zone, and convert the value to the local time zone of the user when it accepts or displays data.  If you take this approach, you will no longer have to tag each date/time data with the time zone which may be a plus depending on your application.

 

Conversion from string to date

In Java, it is possible to parse a monolithic date string that contains month, day and year and convert it to the Date class.  However, this is not recommended when your software receives data input from various regions of the world at the same time.  The following example illustrates the case where the user in the U.S. enters the date " October 12, 2004" in short format "10/12/4", and how this string is interpreted in different locale settings:

 

import java.util.*;

import java.text.*;

 

public class intl35 {

 

  public static void main(String args[])

  {

    String asLanguageCountry[][] = {

       // Western Europe

      { "en", "GB"},

      { "fr", "FR"},

      { "de", "DE"},

      { "es", "ES"},

      { "it", "IT"},

      { "sv", "SE"},

      { "da", "DK"},

      { "nl", "NL"},

 

       // North America

      { "en", "US"},

      { "en", "CA"},

      { "fr", "CA"},

      { "es", "MX"}

    };

    Locale l;

    int i, j;

    DateFormat df;

    DateFormat dfLong;

    String sDate = "10/12/4"; // October 12, 2004 in the U.S. format

    Date d;

 

    // Code

    for(i = 0; i < asLanguageCountry.length; i++){

       l = new Locale(asLanguageCountry[i][0], asLanguageCountry[i][1]);

       System.out.print(l.getDisplayName(Locale.US) + "\t");

 

       df = DateFormat.getDateInstance(DateFormat.SHORT, l);

       dfLong = DateFormat.getDateInstance(DateFormat.LONG, l);

 

       try {

         d = df.parse(sDate);

         if(d == null){

           System.out.print("Date string cannot be parsed." + "\n");

         }

         else{

           System.out.print(dfLong.format(new Date()) + "\n");

         }

       }

       catch(Exception e){

          System.out.print("Date string cannot be parsed: " + e.getMessage() + "\n");

       }

    }

  }

}

intl35.java

The output is shown below:

 

C:\programs\javatest\site>java intl35

English (United Kingdom)        04 October 2002

French (France) 4 octobre 2002

German (Germany)        Date string cannot be parsed: Unparseable date: "10/12/4

"

Spanish (Spain) 4 de octubre de 2002

Italian (Italy) 4 ottobre 2002

Swedish (Sweden)        Date string cannot be parsed: Unparseable date: "10/12/4

"

Danish (Denmark)        Date string cannot be parsed: Unparseable date: "10/12/4

"

Dutch (Netherlands)     Date string cannot be parsed: Unparseable date: "10/12/4

"

English (United States) October 4, 2002

English (Canada)        October 4, 2002

French (Canada) Date string cannot be parsed: Unparseable date: "10/12/4"

Spanish (Mexico)        4 de octubre de 2002

 

As you can see, parse failed for some of the locales.  Even you can make a fairly intelligent guess, you can't conduct a 100%-foolproof parsing, and the risk is not worth taking. For this reason, if you accept a date input from the user, it is much safer to provide three separate fields for month, day and year, and parse each value separately. If this is not possible, you can also put the format that you expect by the input field as many paper forms do.

 

Number format

You can use a similar technique to display the number based on the locale.

The following code displays "12,345.6789" in various locales:

 

import java.util.*;

import java.text.*;

 

public class intl37 {

 

  public static void main(String args[])

  {

    String asLanguageCountry[][] = {

       // Western Europe

      { "en", "GB"},

      { "fr", "FR"},

      { "de", "DE"},

      { "es", "ES"},

      { "it", "IT"},

      { "sv", "SE"},

      { "da", "DK"},

      { "nl", "NL"},

 

       // North America

      { "en", "US"},

      { "en", "CA"},

      { "fr", "CA"},

      { "es", "MX"}

    };

    Locale l;

    int i, j;

    NumberFormat nf;

 

    // Code

    for(i = 0; i < asLanguageCountry.length; i++){

      l = new Locale(asLanguageCountry[i][0], asLanguageCountry[i][1]);

      System.out.print(l.getDisplayName(Locale.US) + "\t");

 

      nf = NumberFormat.getInstance(l);

      System.out.print(nf.format(new Double(12345.6789)) + "\n");

    }

  }

}

intl37.java

 

The output is shown below:

 

C:\programs\javatest\site>java intl37

English (United Kingdom)        12,345.679

French (France) 12 345,679

German (Germany)        12.345,679

Spanish (Spain) 12.345,679

Italian (Italy) 12.345,679

Swedish (Sweden)        12 345,679

Danish (Denmark)        12.345,679

Dutch (Netherlands)     12.345,679

English (United States) 12,345.679

English (Canada)        12,345.679

French (Canada) 12 345,679

Spanish (Mexico)        12,345.679

 

Please note :

l         For Germany, Italy, Spain, Netherlands and Denmark, a period is used for a thousand separator and a comma is used for a decimal separator, which is opposite from the U.S. custom.

l         For France, French Canada and Sweden, a space is used for a thousand separator and a comma is used for a decimal separator.

 

As you can imagine, the conversion from the numeric string to actual number poses the same problem as the conversion from a date string to the Date object.  If the text field in your software accepts a floating point number, the safest way is provide two fields for the integer part and the fractional part. If that is not possible in your software, you may want to clearly mark the format you expect for the numeric field.

 

Currency format

You can also use the same technique for formatting the monetary value using the NumberFormat class, even though there are some issues you need to consider:

 

import java.util.*;

import java.text.*;

 

public class intl38 {

 

  public static void main(String args[])

  {

    String asLanguageCountry[][] = {

       // Western Europe

      { "en", "GB"},

      { "fr", "FR"},

      { "de", "DE"},

      { "es", "ES"},

      { "it", "IT"},

      { "sv", "SE"},

      { "da", "DK"},

      { "nl", "NL"},

 

       // North America

      { "en", "US"},

      { "en", "CA"},

      { "fr", "CA"},

      { "es", "MX"}

    };

    Locale l;

    int i, j;

    NumberFormat nf;

 

    // Code

    for(i = 0; i < asLanguageCountry.length; i++){

      l = new Locale(asLanguageCountry[i][0], asLanguageCountry[i][1]);

      System.out.print(l.getDisplayName(Locale.US) + "\t");

 

      nf = NumberFormat.getCurrencyInstance(l);

      System.out.print(nf.format(new Double(12345.6789)) + "\n");

    }

  }

}

intl38.java

Output is shown below:

 

English (United Kingdom)        £12,345.68

French (France) 12 345,68 €

German (Germany)        12.345,68 €

Spanish (Spain) 12.345,68 €

Italian (Italy) € 12.345,68

Swedish (Sweden)        12 345,68 kr

Danish (Denmark)        kr 12.345,68

Dutch (Netherlands)     € 12.345,68

English (United States) $12,345.68

English (Canada)        $12,345.68

French (Canada) 12 345,68 $

Spanish (Mexico)        $12,345.68

 

This output was obtained under JDK 1.4.0 as shown below:

 

C:\programs\javatest\site>java -version

java version "1.4.0"

Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)

Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)

 

However, if you are using the old version of JDK, old currency symbols will be returned as shown below:

 

C:\programs\javatest\site>java -version

java version "1.3.1_02"

Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1_02-b02)

Java HotSpot(TM) Client VM (build 1.3.1_02-b02, mixed mode)

 

C:\programs\javatest\site>java intl38

English (United Kingdom)        £12,345.68

French (France) 12 345,68 F

German (Germany)        12.345,68 DM

Spanish (Spain) 12.346 Pts

Italian (Italy) L. 12.346

Swedish (Sweden)        12 345,68 kr

Danish (Denmark)        kr 12.345,68

Dutch (Netherlands)     fl 12.345,68

English (United States) $12,345.68

English (Canada)        $12,345.68

French (Canada) 12 345,68 $

Spanish (Mexico)        $12,345.68

 

If your software requires the Euro symbol (0x20AC in Unicode, 0x80 in codepage 1252), you have to make sure that the user is using a JDK version that supports it. In addition, if your software runs on the Microsoft platform, the Euro symbol is supported on Windows XP, Windows 2000, Windows ME, and Windows 98, but the older versions of Windows require installing Microsoft Euro Currency Support solutions1 according to the Microsoft website.  It is expected that more countries will join the EU in the future, so if you want to support the Euro symbol, you may want to keep an eye on the status of the EU membership of the countries that you are targeting your software.

If you just want to obtain the currency code for each locale, you can use the Currency class that is added to JDK 1.4 as shown below.

 

import java.util.*;

import java.text.*;

 

public class intl40 {

 

  public static void main(String args[])

  {

    String asLanguageCountry[][] = {

       // Western Europe

      { "en", "GB"},

      { "fr", "FR"},

      { "de", "DE"},

      { "es", "ES"},

      { "it", "IT"},

      { "sv", "SE"},

      { "da", "DK"},

      { "nl", "NL"},

 

       // North America

      { "en", "US"},

      { "en", "CA"},

      { "fr", "CA"},

      { "es", "MX"}

    };

    Locale l;

    int i, j;

    NumberFormat nf;

    Currency cur;

 

    // Code

    for(i = 0; i < asLanguageCountry.length; i++){

      l = new Locale(asLanguageCountry[i][0], asLanguageCountry[i][1]);

      System.out.print(l.getDisplayName(Locale.US) + "\t");

 

      cur = Currency.getInstance(l);

      System.out.print( "\t" +

                        "ISO-4217 code : " + cur.getCurrencyCode() + "\t" +

                        "\n");

    }

  }

}

 

The output is shown below:

 

C:\programs\javatest\site>java intl40

English (United Kingdom)                ISO-4217 code : GBP

French (France)         ISO-4217 code : EUR

German (Germany)                ISO-4217 code : EUR

Spanish (Spain)         ISO-4217 code : EUR

Italian (Italy)         ISO-4217 code : EUR

Swedish (Sweden)                ISO-4217 code : SEK

Danish (Denmark)                ISO-4217 code : DKK

Dutch (Netherlands)             ISO-4217 code : EUR

English (United States)         ISO-4217 code : USD

English (Canada)                ISO-4217 code : CAD

French (Canada)         ISO-4217 code : CAD

Spanish (Mexico)                ISO-4217 code : MXN

 

In real world applications, displaying numbers in another currency is likely to involve exchange rates.  JDK doesn't provide a pre-made exchange rate calculation mechanism, so it is up to you to implement this.

 

Collation sequence

In internationalizing an application, it is important that all the strings are sorted based on the cultural conventions for each locale.

Shown below is an example of non locale-sensitive source code:

 

import java.util.*;

import java.text.*;

 

public class intl43 {

 

  public static void main(String args[])

  {

    String asLanguageCountry[][] = {

      { "fr", "FR"},

      { "de", "DE"}

    };

 

    String asList[] = {

      "a",

      "e",

      "\u00e9", // e with acute

      "\u00df", // German ess-zed

      "ss",

      "st",

      "z"

    };

 

    Locale l;

    int i, j;

 

    // Code

    for(i = 0; i < asLanguageCountry.length; i++){

      l = new Locale(asLanguageCountry[i][0], asLanguageCountry[i][1]);

      System.out.print(l.getDisplayName(Locale.US) + "\n");

 

      Arrays.sort(asList);

      for(j = 0; j < asList.length; j++){

        System.out.print( "[" + Integer.toString(j) + "] " +

                            asList[j] +

                            "\n");

      }

      System.out.print("\n");

    }

  }

}

intl43.java

 

Output is shown below:

 

C:\programs\javatest\site>java intl43

French (France)

[0] a

[1] e

[2] ss

[3] st

[4] z

[5] ß

[6] é

 

German (Germany)

[0] a

[1] e

[2] ss

[3] st

[4] z

[5] ß

[6] é

 

Please note that both "ess-zed" and "e with acute accent" are sorted after the letter "z".

 

However, in German, even though "ess-zed" is a ligature of "s" and "z", it is treated as equivalent of "ss" in sorting.  For example, in Langenscheidt's German-English dictionary, the word "Mißklang" is sorted after "Mission", but before "Mist".

So in the example above, "ß" should be placed before "st".

Similarly, for French, "é" should be placed after "e" (for example, in Larousse's French-English dictionary, "frisé" is listed immediately after "frise").

 

To correct the problem, the following changes were made:

 

      Arrays.sort(asList);

Locale-insensitive code (old)

 

     col = Collator.getInstance(l);

      col.setStrength(Collator.IDENTICAL); // case-sensitive

      col.setDecomposition(Collator.FULL_DECOMPOSITION);

      Arrays.sort(asList, col);

Locale-sensitive code (new)

 

Instead of simply using the natural order sorting in the Arrays.sort method, we obtain the instance of the locale-sensitive Collator class and use it to sort the list of strings. The complete code is shown below:

 

import java.util.*;

import java.text.*;

 

public class intl44 {

 

  public static void main(String args[])

  {

    String asLanguageCountry[][] = {

      { "fr", "FR"},

      { "de", "DE"}

    };

 

    String asList[] = {

      "a",

      "e",

      "\u00e9", // e with acute

      "\u00df", // German ess-zed

      "ss",

      "st",

      "z"

    };

 

    Locale l;

    int i, j;

    Collator col;

 

    // Code

    for(i = 0; i < asLanguageCountry.length; i++){

      l = new Locale(asLanguageCountry[i][0], asLanguageCountry[i][1]);

      System.out.print(l.getDisplayName(Locale.US) + "\n");

 

      col = Collator.getInstance(l);

      col.setStrength(Collator.IDENTICAL); // case-sensitive

      col.setDecomposition(Collator.FULL_DECOMPOSITION);

      Arrays.sort(asList, col);

      for(j = 0; j < asList.length; j++){

        System.out.print( "[" + Integer.toString(j) + "] " +

                            asList[j] +

                            "\n");

      }

      System.out.print("\n");

    }

  }

}

intl44.java

 

As shown in the output below, the strings are sorted correctly this time:

C:\programs\javatest\site>java intl44

French (France)

[0] a

[1] e

[2] é

[3] ss

[4] ß

[5] st

[6] z

 

German (Germany)

[0] a

[1] e

[2] é

[3] ss

[4] ß

[5] st

[6] z

 

If your application simply returns the list of strings in the database, you will also have to check to see if database is returning the strings in a locale-sensitive order.

 

Name format

The display order of the first name and the last name is also locale-dependent.  In English, if you want to display the name "Mr. John Doe Jr.", the following formats are typically used:

l         John Doe,

l         John Doe Jr.

l         Doe, John

l         Mr. John Doe

l         Mr. John Doe Jr.

 

However, in Japanese, the most common format will be the last name followed by the first name.  The space between the last name and the first name may be omitted depending on the style guideline that is used for the document. To cope with this, you may want to implement a class that returns the names in the String format based on your target locale.  If you name the name formatter class "xNameFormat", the example will be:

 

sName = sFirstName + " " + sFirstName;

Locale-insensitive code (old)

 

xNameFormat nf = xNameFormat.getNameInstance(xNameFormat.LONG, lLocale);

sName = nf.format(sLastName, sFirstName);

  Locale-sensitive code (new)

 

Support of pronunciation data for name for the Japanese market

If your software supports the Japanese market, another issue you may have to consider is the support of pronunciation data for names.  Since one Kanji has multiple ways of pronouncing it, it is common to have a separate pronunciation field in a form.  This data for pronunciation is known as "Furigana".  What this means is that if you are storing data in your database, you may have to make extensive changes to support this feature. The list of the changes will be:

 

l         Additional columns in database tables or views to store these data

l         Additional fields in user interface to enter, look-up and display these data

l         Additional code to support these features

 

Since the names are expected to be ordered by pronunciation rather than by the code point of Kanji regardless of whether the pronunciation data itself is displayed, the cost of making these changes should not be underestimated.

Since the cost of implementing these features is high, before you implement these features, you might want to check with your sales representative or distributors in Japan to see if this is needed for your product.

 

Address format

The format of address is also locale-dependent.  If you concatenate the address elements to a single string, you may want to design a class that formats an address based on the target locale.  This approach is similar to the xNameFormat class as we discussed earlier.

One issue to consider is if your product supports an address lookup from the ZIP code, the feature has to be extended to support ZIP codes for other countries.  For example, if you want to support the postal code lookup in Japan, you have to add the 7-digit postal codes to your database, and implement the mechanism to look it up.  When you design the initial schema, you may want to keep this in mind so that your design can be extensible to support more countries easily in the future as the need arises.

 

Unit of measurement - Metric (SI) or pound/feet

If your product displays units of measurement with any values, you have to make sure that the metric system can be also used or selected as the main unit of measurement.

For printing, if your software supports printing in the Letter size by default, make sure that A4 can be selected as default for the international market.