Currency Updates in J2SE 1.4

Copyright (c) 2002 John O'Conner

 

T

he Java 2 platform has always been able to format numbers using locale-dependent formatting rules and symbols. It can even format currency amounts for a specific locale. However, it hasn’t always been able to easily combine the formatting preferences of one locale with the currency of another. For example, although applications could print the number 1234 as a French Franc currency using the fr_FR locale, they haven't always been able to use the fr_FR formatting with another currency, maybe the German Mark. In international business, the ability to use foreign currencies with one’s own number formats is an important and necessary feature. The Java 2 Standard Edition (J2SE) version 1.4 corrects some of this deficiency by introducing the java.util.Currency class.

Let’s Review

Your applications can format a currency value using a java.text.NumberFormat instance. The typical way to use this class would be like this:

// value can be retrieved from a separate calculation

double value = 12345.567;

Locale defaultLocale = Locale.getDefault();

NumberFormat nf = NumberFormat.getCurrencyInstance(defaultLocale);

String formattedValue = nf.format(value);

System.out.println(formattedValue);

 

In a fr_FR locale using the J2SE 1.3, the result would be

12 345,57 F

 

However, how does your application specify the Euro currency? Before J2SE version 1.4, you had to create a separate Locale object for this, fr_FR_EURO. The resulting code would look like this:

// value can be retrieved from a separate calculation

double value = 12345.567;

// locale preference should be retrieved from user preferences

Locale defaultLocale = new Locale("fr", "FR", "EURO");

NumberFormat nf = NumberFormat.getCurrencyInstance(defaultLocale);

String formattedValue = nf.format(value);

System.out.println(formattedValue);

 

The result would be:

12 345,57 €

 

However, using a variant locale is a rather clunky way to deal with currency preferences, especially in multi-currency countries. Also, variant locales for Euro preference only work for Western European countries that intend to standardize on the Euro. You could not, for example, create a NumberFormat for the fictional en_US_EURO locale (for Euro usage in the U.S.). A more uniform way to use alternative currencies within a locale's typical currency format pattern is necessary.

Introducing the Currency Class

The Java platform introduces the java.util.Currency class in its latest 1.4 version, which is still in beta phase. Currency objects represent national currencies. You create objects in two ways:

1.      public static Currency getInstance(Locale aLocale)
Use a Locale argument to create the default currency object for a specific locale.

2.      public static Currency getInstance(String currencyCode)
Use a currency identifier to create a specific currency object regardless of locale.

Currency identifiers are ISO 4217 codes, which are 3 letter abbreviations. You can find a list of current currency identifiers at the British Standards Institution's website. A few of these codes are shown in the table below.

Figure 1 A few currency codes from around the world

Currency Code

Currency

USD

United Stated Dollar

ITL

Italian Lira

DEM

German Mark

HKG

Hong Kong Dollar

MXN

Mexican Peso

EUR

Euro

 

Using the Currency class in J2SE 1.4, we now have the tools to print a EUR currency value using a fr_FR format object[1]. The previous code example can now be rewritten:

// value can be retrieved from a separate calculation

double value = 12345.567;

// locale preference should be retrieved from user preferences

Locale aLocale = new Locale("fr", "FR");

NumberFormat nf = NumberFormat.getCurrencyInstance(defaultLocale);

Currency newCurrency = Currency.getInstance("EUR");

nf.setCurrency(newCurrency);

String formattedValue = nf.format(value);

System.out.println(formattedValue);

 

This would print

12 345,57 €

 

Although many European countries will standardize on the Euro after January 1 2002, England will continue to use its English Pound. However, there will definitely be opportunities for English business to complete transactions using the Euro. In that situation, they will not want to use their default currency. The following code shows a currency value printed for a British customer using both the Pound and the Euro.

 

double value = 12345.678;

Locale l = new Locale("en", "GB");

System.out.println(l.getDisplayName());

 

NumberFormat nf = NumberFormat.getCurrencyInstance(l);

System.out.println(nf.format(value));

 

Currency currency = Currency.getInstance("EUR");

nf.setCurrency(currency);

System.out.println(nf.format(value));

 

This code prints the following:

      English (United Kingdom)

£12,345.68

€12,345.68

 

The ability to print the EUR currency symbol instead of the currency code is dependent on the Java 2 Runtime Environment (J2RE) localization level. Some runtime vendors may provide localized currency symbols for many or all currencies. The Sun Microsystems runtime provides only a few. The Euro symbol, for example, is provided for those Western European locales that will use the Euro currency by default or by other necessity in 2002. NumberFormat objects for other locales do not retrieve a localized symbol for foreign currencies. In that situation, the format object will simply use the foreign currency code. We can demonstrate that behavior by printing a Euro currency amount using an en_US NumberFormat. The code is shown below:

double value = 12345.567;

NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.US);

Currency currency = Currency.getInstance("EUR");

nf.setCurrency(currency);

String formattedValue = nf.format(value);

System.out.println(nf);

 

Instead of €12,345.57, the result is

EUR12,345.57

Summary

Beginning with J2SE 1.4, a Currency class is available. This class represents a a national or regional currency. You can use instances of Currency to change the currency used by NumberFormat objects.



[1] As it turns out, the default currency for  fr_FR is the Euro since January 1, 2002.