In Java, why does the decimal separator follow the Locale's language, not its country, and, more importantly, how does one override it?

Mark Hanes picture Mark Hanes · Feb 17, 2010 · Viewed 15.6k times · Source

I'm working on an international project and have observed that, in Java, the choice of the decimal separator is based on the Locale's language, not its country. For example:

DecimalFormat currencyFormatter = (DecimalFormat) NumberFormat.getInstance(new Locale("it","IT"));
System.out.println(currencyFormatter.format(-123456.78));

currencyFormatter = (DecimalFormat) NumberFormat.getInstance(new Locale("en","IT"));
System.out.println(currencyFormatter.format(-123456.78));

produces the following output:

-123.456,78
-123,456.78

I would have expected it to follow the country, since if I'm in the country, whether I speak English or Italian the numbers in that country are written with the decimal separator as comma.

My question is two-fold:

  1. Does anyone know why this behaviour follows the language?
  2. More importantly, can anyone offer details as to how to modify the default behaviour in Java to follow the language instead?

Thanks.

Answer

Joachim Sauer picture Joachim Sauer · Feb 17, 2010

It is very, very likely that there is no known "en_IT" locale on your system and that Java knows of no such locale.

Therefore you'll get the resources for the closest matching Locale, as per this note in the JavaDoc of Locale:

When you ask for a resource for a particular locale, you get back the best available match, not necessarily precisely what you asked for. For more information, look at ResourceBundle.

The relevant documentation in ResourceBundle shows that the country alone is never attempted as the identifier to find a given resource. Only the language, the language + the country and the language + the country + the variant are used.