Search code examples
javainternationalizationlocalenumber-formattingcurrency-formatting

Formatting number based on the different currency code for different locale where output to be in the currency symbol formatted based on the locale


Language: Java Problem: I need to set the currency code manually in java. Let's say "USD" and locale can be either "fr-CA" or "en_US" based on the user logged in . I am unable to find the solution where we can do the number format by setting the manual currency and displaying the symbol with number in the output. Please note currency code will not be the same as the locale and vice versa.

For example, if my currency is USD then based on the different locale, the number should be formatted and the output should be as below. $1,300,000.00 - english 1.300.000,00 $ - Deutch 1 300 000,00 US$ - Potuguese 1 300 000,00 $ US - France canada

Tried below but it does not give the expected output:

Currency currencyInstance1 = Currency.getInstance("USD"); // This can change based on the user input on the UI.
NumberFormat numberFormat4 = NumberFormat.getCurrencyInstance(Locale.CANADA_FRENCH);
numberFormat4.setCurrency(currencyInstance1);
System.out.println(numberFormat4.format(amount4));

Actual output : 123 456,79 USD
**Expected output:**
For french canada:  1 300 000,00 $ US
For Portuguese : 1 300 000,00 US$
For Deutch : 1.300.000,00 $

Any help is appreciated.

Solution

  • Country codes are an important locale component because of java. text.Format objects for dates, time, numbers, and currency are particularly sensitive to this element. Country codes add precision to the language component of a locale. For example, French is used in both France and Canada. However, precise usage and idiomatic expressions vary in the two countries. These differences can be captured with different locale designators in which only the country code is different. For example, the code fr_CA (French-speaking Canada) is different from fr_FR (French-speaking France).

    So if we need to fetch the symbol then we would need to create a map with the locale and currency. Pass the currency to fetch the symbol and then use replace to add it.

    public static Map<Currency, Locale> currencyLocaleMap;
    
        static {
            currencyLocaleMap = new HashMap<>();
            List<Locale> availableLocales = 
            Arrays.asList(Locale.getAvailableLocales());
    
            List<Locale> supportedLocales = new ArrayList<>();
            supportedLocales.add(Locale.forLanguageTag("en-US"));
    
            List<Locale> filteredLocales = supportedLocales.stream().filter
                    (eachLocale -> availableLocales.contains(eachLocale)).collect(Collectors.toList());
            System.out.println("UtilTemp : Locales supported : " + filteredLocales); 
    
            for (Locale locale : filteredLocales) {
                try {
                    if(!locale.getCountry().isEmpty()){
                        Currency currency = Currency.getInstance(locale);
                        currencyLocaleMap.put(currency, locale); 
                    }
                }
                catch (Exception e) {
                }
            }
        }
    
        public static String getCurrencySymbol(String currencyCode) {
            Currency currency = Currency.getInstance(currencyCode);
            System.out.println("UtilTemp :" +  currencyLocaleMap);
            return currency.getSymbol(currencyLocaleMap.get("USD"));
        }