Multi-currency support in Java

November 20, 2017 | Romain Guefveneu | 3-minute read

For a few weeks, Drivy has been available in the United-Kingdom. Unlike the others European countries where Drivy operates, the United-Kingdom uses a different currency: the pound (£). We had to make some changes in our Android apps to support this.

Server-side or Client-side Formatting?

At Drivy, formatting is generally done server-side, we just display the values as they are:

Here, prices are formatted server-side, depending on the search place (London, so £), and the app’s locale (french).

But for some specific features we need client-side formatting, for instance an input field. Let’s dive into some Java APIs to see how they can help.

Formatting

First thing first, how to format a currency? The position of the currency symbol doesn’t depend on the currency itself, but on the country of the locale. That means we’ll display “1 234,50 GBP” in French, and “€1,234.50” in English:

  £ $
France 1 234,50 € 1 234,50 GBP 1 234,50 USD
Switzerland EUR 1’234.50 GBP 1’234.50 USD 1’234.50
Italy € 1.234,50 GBP 1.234,50 USD 1.234,50
United-Kingdom €1,234.50 £1,234.50 USD1,234.50
USA EUR1,234.50 $1,234.50 $1,234.50

As you can see, the currency symbol is not always displayed. Since there are multiple currencies using the same symbol (e.g. United States dollar and Canadian dollar), we will instead display the currency code if there is any ambiguity (well, except for € in en_US 🤷‍).

Alright, how do we do that in Java? Pretty simple:

Locale countryLocale = Locale.FRANCE;
Locale currencyLocale = Locale.UK;

NumberFormat currencyFormat = NumberFormat.getCurrencyInstance(countryLocale);
Currency currency = Currency.getInstance(currencyLocale);
currencyFormat.setCurrency(currency);

System.out.println(currencyFormat.format(1234.5f));
//1 234,50 GBP

If we dig a bit deeper, we can extract the format pattern:

DecimalFormat currencyFormat = (DecimalFormat) NumberFormat.getCurrencyInstance(Locale.FRANCE);
System.out.println(currencyFormat.toPattern());
//#,##0.00 ¤

#,##0.00 ¤ is the French currency format, and it doesn’t depend on any currency. ¤ is the currency symbol and behaves like a placeholder for the currency symbol or code.

Input field

Building our own currency input field is not very complicated. The main issue to solve is to know where to draw the currency symbol. Indeed, depending on the currency format, we have seen that the symbol can be either before the value or after the value. As we certainly don’t want to parse the format pattern, these four DecimalFormat methods will be useful:

  • getNegativePrefix()
  • getPositivePrefix()
  • getNegativeSuffix()
  • getPositiveSuffix()

Here are some interesting values:

  NegativePrefix PositivePrefix NegativeSuffix PositiveSuffix Example
France -   -1 234,50 €
Denmark kr - kr     kr -1.234,50
Netherlands -   € 1.234,50-
United-Kingdom £     -£1,234.50
USA ($ $ )   ($1,234.50)

Now all we have to do is to draw the prefix and postfix!

Conclusion

With the help of just a few provided APIs, we have seen that formatting a currency can be easy. So don’t try and format currencies by hand!

View openings 👍  Like this post? Join Drivy's engineering team!