Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Formatting Currencies in Foreign Locales in Java

I'm doing my best to find a way to format foreign currencies across various locales which are not default for that currency, using Java. I've found java.util.Currency, which can represent the proper symbol to use for various locales. That is, for USD, it provides me the symbol $ in the US, and US$ or USD in other nations. Also, I've found java.text.NumberFormat, which will format a currency for a specific locale. My problem - util.Currency will provide proper symbols and codes for representing currencies in their non-default locales, but will not format currency in any locale-specific way. NumberFormat assumes that the number I pass it, with a locale, is the currency of that locale, not a foreign currency.

For example, if I use getCurrencyInstance(Locale.GERMANY) and then format (1000) it assumes I am formatting 1000 euro. In reality, I may need the correct German-localized representation (correct decimal and thousands separator, whether to put the symbol before or after the amount) for USD, or Yen, or any other currency. The best I've been able to derive so far is to format a number using NumberFormat, then search the output for non-digit characters and replace them with symbols derived from util.Currency. However, this is very brittle, and probably not reliable enough for my purposes. Ideas? Any help is much appreciated.

like image 260
JPittard Avatar asked Oct 19 '11 21:10

JPittard


People also ask

How do you format currencies in Java?

Java provides an automated way for formatting currencies depending on the locale. getCurrencyInstance() is a static method of the NumberFormat class that returns the currency format for the specified locale. Note: A Locale in Java represents a specific geographical, political, or cultural region.

How do you add currency in Java?

The setCurrency() method is a built-in method of the java. text. NumberFormat which sets the currency used by this number format when formatting currency values. This does not update the minimum or maximum number of fraction digits used by the number format.

How can I get currency from locale?

The getSymbol() method is used to get the symbol of a given currency for the default DISPLAY locale. For example, for the US Dollar, the symbol is "$" if the default locale is the US, while for other locales it may be "US$". If no symbol can be determined, the ISO 4217 currency code is returned.


3 Answers

Try using setCurrency on the instance returned by getCurrencyInstance(Locale.GERMANY)

Broken:

java.text.NumberFormat format = java.text.NumberFormat.getCurrencyInstance(java.util.Locale.GERMANY); System.out.println(format.format(23)); 

Output: 23,00 €

Fixed:

java.util.Currency usd = java.util.Currency.getInstance("USD"); java.text.NumberFormat format = java.text.NumberFormat.getCurrencyInstance(java.util.Locale.GERMANY); format.setCurrency(usd); System.out.println(format.format(23)); 

Output: 23,00 USD

like image 88
les2 Avatar answered Oct 14 '22 21:10

les2


I would add to answer from les2 https://stackoverflow.com/a/7828512/1536382 that I believe the number of fraction digits is not taken from the currency, it must be set manually, otherwise if client (NumberFormat) has JAPAN locale and Currency is EURO or en_US, then the amount is displayed 'a la' Yen', without fraction digits, but this is not as expected since in euro decimals are relevant, also for Japanese ;-).

So les2 example could be improved adding format.setMaximumFractionDigits(usd.getDefaultFractionDigits());, that in that particular case of the example is not relevant but it becomes relevant using a number with decimals and Locale.JAPAN as locale for NumberFormat.

    java.util.Currency usd = java.util.Currency.getInstance("USD");     java.text.NumberFormat format = java.text.NumberFormat.getCurrencyInstance(           java.util.Locale.JAPAN);     format.setCurrency(usd);     System.out.println(format.format(23.23));     format.setMaximumFractionDigits(usd.getDefaultFractionDigits());     System.out.println(format.format(23.23)); 

will output:

USD23 USD23.23 

In NumberFormat code something similar is done for the initial/default currency of the format, calling method DecimalFormat#adjustForCurrencyDefaultFractionDigits. This operation is not done when the currency is changed afterwards with NumberFormat.setCurrency

like image 28
Testo Testini Avatar answered Oct 14 '22 20:10

Testo Testini


import java.util.*;
import java.text.*;

public class Solution {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        double payment = scanner.nextDouble();
        scanner.close();

        NumberFormat lp;  //Local Payment

        lp = NumberFormat.getCurrencyInstance(Locale.US);
        System.out.println("US: " + lp.format(payment));

        lp = NumberFormat.getCurrencyInstance(new Locale("en", "in"));
        System.out.println("India: " + lp.format(payment));

        lp = NumberFormat.getCurrencyInstance(Locale.CHINA);
        System.out.println("China: " + lp.format(payment));

        lp = NumberFormat.getCurrencyInstance(Locale.FRANCE);
        System.out.println("France: " + lp.format(payment));
    }
}
like image 25
Ankush Avatar answered Oct 14 '22 21:10

Ankush