Search code examples
javaformattinglocale

Currency symbol with another number format


I was wondering if there was an elegant way to set the currency format of a number in one way but keep the actual number formatting in another. It is Java. Essentially I am doing this

NumberFormat format = NumberFormat.getCurrencyInstance(locale);  

This is largely fine except I am writing a system for UK based users and my users are upset that when showing (for example) euros the number is formatted as europeans would use it. So € 500,000 as a UK person would write it is displaying as € 500.000 (i.e. swap , for .). I was going to swap locale for locale.UK but then I will have the wrong currency symbol!

I have a couple of dirty fixes for this but I wondered if there was an elegant way to keep the currency symbol of the locale with the local locale (locale.UK) number format.


Solution

  • Different currencies can also place the currency symbol before or after the string, or have a different number of decimal places (if any). It is not really clear from your question how you want to handle those cases, but assuming you want to preserve those differences, try this.

    Instead of just swapping in the currency symbol into your local number format, you could start with the foreign format and substitute the decimal format symbols with your local version. Those also include the currency, so you have to swap that back (don't worry, it's a copy).

    public static NumberFormat localStyleForeignFormat(Locale locale) {
        NumberFormat format = NumberFormat.getCurrencyInstance(locale);
        if (format instanceof DecimalFormat) {
            DecimalFormat df = (DecimalFormat) format;
            // use local/default decimal symbols with original currency symbol
            DecimalFormatSymbols dfs = new DecimalFormat().getDecimalFormatSymbols();
            dfs.setCurrency(df.getCurrency());
            df.setDecimalFormatSymbols(dfs);
        }
        return format;
    }
    

    This way, you also retain the correct positioning of the currency symbol and the number of decimal places. Some examples, for default-Locale Locale.UK

    en_GB   £500,000.00     £500,000.00
    fr_FR   500 000,00 €    500,000.00 €
    it_IT   € 500.000,00    € 500,000.00
    ja_JP   ¥500,000       JPY500,000
    hi_IN   रू ५००,०००.००    INR 500,000.00
    

    If you also want to preserve the foreign currency symbol, instead of the local equivalent, use

    localDfs.setCurrencySymbol(df.getCurrency().getSymbol(locale));