In Java, why does the decimal separator follow the

2019-04-06 13:48发布

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.

8条回答
等我变得足够好
2楼-- · 2019-04-06 14:39

1.- Does anyone know why this behaviour follows the language?

One of the first aspects that change in an application according to its locale is the language. Think of Switzerland, where they have both French and German as official languages. Using the country in this scenario makes no sense because, besides currency there are other aspect ( such as display messages, to take into consideration )

Same goes for a number of countries ( Canada is other that comes to my mind).

The country is an option to specialize that language.

Since there is no "Italian English" en_IT doesn't make much sense. So it takes "english" and that's why the returned instance is the one with "en" English.

2.- More importantly, can anyone offer details as to how to modify the default behavior in Java to follow the language instead?

You mean, the country right?

The answer is in the method: NumberFormat.getAvailableLocales() which in turn leads you to: NumberFormatProvider which is an abstract class you can extend to return the correct NumberFormat for "en_IT" ( which pretty much will return it_IT )

How to install that new class goes beyond my knowledge, but I think you'll have to hack it somewhere in the jre directory.

EDIT

As I suspect the class should be installed under jre/ext folder and that's it.

There is a project somewhere else which did something similar to support "gl_ES" ( Galician )

Here's instructions on how to install it and what it is all about:

http://www.javagalician.org/install.html

So, basically, if you want to provide a bunch of instances for Italy ( or even better a single one ) , you just have to create one instance of the NumberFormatProvider and have it responding all the languages available.

查看更多
Viruses.
3楼-- · 2019-04-06 14:41

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.

查看更多
登录 后发表回答