Displaying Currency in Indian Numbering Format

Mihir picture Mihir · Mar 21, 2011 · Viewed 88.2k times · Source

I have a question about formatting the Rupee currency (Indian Rupee - INR).

Typically a value like 450500 is formatted and shown as 450,500. In India, the same value is displayed as 4,50,500

For example, numbers here are represented as:

1
10
100
1,000
10,000
1,00,000
10,00,000
1,00,00,000
10,00,00,000

Refer Indian Numbering System

The separators are after two digits, except for the last set, which is in thousands.

I've searched on the internet and people have asked to use the locale en_GB or pattern #,##,##,##,##0.00

I tried this on JSTL by using the following tag:

<fmt:formatNumber value="${product.price}" type="currency" 
  pattern="#,##,##,##,###.00"/>

But this does not seem to solve the issue. Any help in this matter will be greatly appreciated.

Thanks

Answer

Joachim Sauer picture Joachim Sauer · Mar 21, 2011

Unfortunately on standard Java SE DecimalFormat doesn't support variable-width groups. So it won't ever format the values exactly as you want to:

If you supply a pattern with multiple grouping characters, the interval between the last one and the end of the integer is the one that is used. So "#,##,###,####" == "######,####" == "##,####,####".

Most number formatting mechanisms in Java are based on that class and therefore inherit this flaw.

ICU4J (the Java version of the International Components for Unicode) provides a NumberFormat class that does support this formatting:

Format format = com.ibm.icu.text.NumberFormat.getCurrencyInstance(new Locale("en", "in"));
System.out.println(format.format(new BigDecimal("100000000")));

This code will produce this output:

Rs 10,00,00,000.00

Note: the com.ibm.icu.text.NumberFormat class does not extend the java.text.NumberFormat class (because it already extends an ICU-internal base class), it does however extend the java.text.Format class, which has the format(Object) method.

Note that the Android version of java.text.DecimalFormat class is implemented using ICU under the hood and does support the feature in the same way that the ICU class itself does (even though the summary incorrectly mentions that it's not supported).