简体   繁体   中英

Currency Symbol Internationalization Java

I'm trying to get the number format according to current locale but I have a problem with the currency symbol.

This is my method:

import java.util.Locale;
import java.text.NumberFormat;

public void i18nCurrency(Locale currentLocale) {
    Double price = 9876543.21; 
    NumberFormat currencyFormatter = 
            NumberFormat.getCurrencyInstance(currentLocale);
    System.out.println(currencyFormatter.format(price));
}

It prints: ¤ 9 876 543,21 for uk and ¤9.876.543,21 for german. The number format is correct, but I need to get the currency symbol as well. Why I can't get the symbol?

The symbol you're getting is a universal currency placeholder. It is displayed when currency is unknown.
You probably wonder why it is unknown. Well, from your description you simply called the method passing something like Locale.GERMAN . If you did, there is no way of knowing what currency to use, because:

  • Euro is a currency of Germany and Austria
  • Swiss Frank (SFr.) is a currency of Switzerland

Each of these countries has German as at least one of their official languages. In order to resolve the problem, you always need to pass a country, ie call the method with Locale.GERMANY as a parameter.

Now, the harder part. It is all fairly easy when you are working with desktop application. All you have to do is to detect current OS locale like this:

Locale currentLocale = Locale.getDefault(LocaleCategory.FORMAT);

However, this method won't work with web applications. I suspect this is the case. Well, the Locale that web browsers give you might be not suitable for formatting currencies, as they may lack information about the country.
The recommended way to solve this issue is to create user profile and ask users to select the Locale (separately for UI translations and formatting purposes).

I still have to point out one important thing, because I don't want you to run into problems. When you have some monetary value in your application (usually it should be an instance of BigDecimal class, as double is not suitable for this purpose), it represents some value in a specific currency . Be it Euro, British Pound, or a Dollar, but the value is specific. It doesn't really make sense to format this value for specific country currency, as you should first change the amount (I believe you understand why).
What you probably need instead, is overriding the currency symbol or currency code to match your currency. The format and the symbol placement should obviously stay intact.

Please consider this example:

Currency dollar = Currency.getInstance("USD");
NumberFormat fmt = NumberFormat.getCurrencyInstance(Locale.GERMANY); //this gets € as currency symbol
BigDecimal monetaryAmount = BigDecimal.valueOf(12.34d);
String originalEuros = fmt.format(monetaryAmount);
System.out.println(originalEuros);

fmt.setCurrency(dollar);  // change the currency symbol to $
String modifiedDollars = fmt.format(monetaryAmount);
System.out.println(modifiedDollars);

This prints:

12,34 €
12,34 USD

Wait, why? The answer to your question lies in this subtle code snippet:

System.out.println(currency.getSymbol(Locale.GERMANY));
System.out.println(currency.getSymbol(Locale.US));

The result:

USD
$

What gets printed depends on a Locale. It is probably better this way, I cannot tell...
I believe, unless you are creating Internet currency exchange application, you should stick to my example.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM