Formatting Currencies in Foreign Locales in Java
Asked Answered
S

8

48

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.

Strander answered 19/10, 2011 at 21:25 Comment(3)
1) are you to display this data somewhere in the GUI, 2) I never tried (ISO Ccy codes rellevant) then my question are you tried print_out symbol for USD, AUD, SGD maybe is there symbol $, 3) I suggest to look for ISO codes rather that mixing and set different Locale, for example since out_dated oanda.com/help/currency-iso-code-country but first from google,Nyaya
It's reasons related to this that you shouldn't store money in a primitive 'on-their-own': they should be part of a class that also contains the currency they represent (500 USD is not 500 yen).Overtask
Did you see the answer I gave below? Does that solve the problem?Thorvald
T
62

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

Thorvald answered 19/10, 2011 at 21:39 Comment(3)
Better checkout Testo Testini's answer below.Thorvald
Frankly, this is still broken from Java. Optimal output should have been Output: 23,00 $Vietnam
@Vietnam no, that isn't the optimal output. That's just wrong. To get that output you have to use the US-Locale. Currency symbols aren't matched 1:1 to currency codes. So the same currency symbol can have a different meaning in a different locale. This is why you are only allowed to use currency symbols if locale and currency match.Greegree
S
29

I would add to answer from les2 https://mcmap.net/q/352921/-formatting-currencies-in-foreign-locales-in-java 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

Sprayberry answered 28/9, 2013 at 22:1 Comment(5)
Good catch. This really is tedious enough to mandate being a utility library, e.g., commons-currency. Does one exist? CurrencyUtils.getFormatter(Locale, Currency).format(BigDecimal)Thorvald
Leaving this for anyone who might be bitten by this behaviour: On Android (specifically, Samsung Galaxy Note 2 with 4.3), with locale de_CH (Deutsch (Schweiz)), if I get the default currency formatter, and call setCurrency("CAD"), I will get "Swedish" rounding. That is, a value of 26.98 gets formatted to 27.00! But with setCurrency("USD"), I don't see this behaviour. Calling setMaximumFractionDigits() as above seems to resolve things, but it doesn't make sense to me, since both CAD and USD use 2 fractional digits by default.Mallarme
This only solves the problem for the maximum number of fraction digits displayed. Everything else, such as rounding behavior and placement of currency symbol will keep the settings of the native currency for the specified locale.Nauplius
@Mallarme I tried your example but I see no rounding with CAD, and also if using JPY, that has no fraction digits. The fraction digits value (2) come from the "Schweizer Franken" initial/default currency of Locale "de_CH". See also updated answer.Sprayberry
@Nauplius placement of currency symbol I think is correctly locale-specific (eg: french people put symbol after amount for any currency). Could you expand on the rounding behavior ? May be with an example. Thanks.Sprayberry
C
14
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));
    }
}
Changeless answered 27/1, 2017 at 8:32 Comment(1)
This is a complete code for currency formatter for some countries.Changeless
F
3
Scanner scanner = new Scanner(System.in);
double payment = scanner.nextDouble();
scanner.close();
java.text.NumberFormat formatUS = java.text.NumberFormat.getCurrencyInstance(java.util.Locale.US);
String us=formatUS.format(payment);
java.text.NumberFormat formatIn = java.text.NumberFormat.getCurrencyInstance(new java.util.Locale("en","in"));
String india=formatIn.format(payment);
java.text.NumberFormat formatChina = java.text.NumberFormat.getCurrencyInstance(java.util.Locale.CHINA);
String china=formatChina.format(payment);
java.text.NumberFormat formatFrance = java.text.NumberFormat.getCurrencyInstance(java.util.Locale.FRANCE);
String france=formatFrance.format(payment);

System.out.println("US: " + us);
System.out.println("India: " + india);
System.out.println("China: " + china);
System.out.println("France: " + france);
Filberte answered 24/1, 2018 at 16:27 Comment(0)
P
3

Code below, Ref Java Locale:

Scanner scanner = new Scanner(System.in);
double payment = scanner.nextDouble();
scanner.close();

// Write your code here.
String china = NumberFormat.getCurrencyInstance(new Locale("zh", "CN")).format(payment);
String india = NumberFormat.getCurrencyInstance(new Locale("en", "IN")).format(payment);
String us = NumberFormat.getCurrencyInstance(Locale.US).format(payment);
String france = NumberFormat.getCurrencyInstance(Locale.FRANCE).format(payment);

System.out.println("US: " + us);
System.out.println("India: " + india);
System.out.println("China: " + china);
System.out.println("France: " + france);
Pym answered 10/7, 2019 at 14:22 Comment(0)
P
1

Better way is just to import java.util.Locale.

Then use the method like this:

NumberFormat.getCurrencyInstance(Locale.theCountryYouWant);

e.g. NumberFormat.getCurrencyInstance(Locale.US);

Psalms answered 2/7, 2018 at 16:32 Comment(0)
D
0

    import java.util.*;
    import java.text.*;
    public class CurrencyConvertor {   
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            double curr= scanner.nextDouble();
            scanner.close();
            if(curr>=0 && curr<=1000000000){
     NumberFormat france = NumberFormat.getCurrencyInstance(Locale.FRANCE);
    NumberFormat us = NumberFormat.getCurrencyInstance(Locale.US);
    NumberFormat china = NumberFormat.getCurrencyInstance(Locale.CHINA);
            NumberFormat india = NumberFormat.getCurrencyInstance(Locale.ENGLISH);
             
          System.out.println("India: "+NumberFormat.getCurrencyInstance(new Locale("en","IN")).format(curr)); 
           System.out.println("US: " + us.format(curr));
          System.out.println("China: "+ china.format(curr));
            System.out.println("France: " + france.format(curr));
            }
        }
    }

Dronski answered 12/7, 2021 at 9:45 Comment(0)
C
0

Try this, Using Locale, you can pass the country and get the currency.

Locale currentLocale = Locale.GERMANY;
Double currencyAmount = new Double(9876543.21);
Currency currentCurrency = Currency.getInstance(currentLocale);
NumberFormat currencyFormatter = 
    NumberFormat.getCurrencyInstance(currentLocale);

System.out.println(
    currentLocale.getDisplayName() + ", " +
    currentCurrency.getDisplayName() + ": " +
    currencyFormatter.format(currencyAmount));

Output: German (Germany), Euro: 9.876.543,21 €

Crapshooter answered 24/8, 2022 at 11:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.