8

我正在从事一个国际项目并观察到,在 Java 中,小数点分隔符的选择是基于区域设置的语言,而不是它的国家。例如:

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));

产生以下输出:

-123.456,78
-123,456.78

我原以为它会跟随这个国家,因为如果我在这个国家,无论我说英语还是意大利语,那个国家的数字都是用逗号分隔的小数点。

我的问题有两个:

  1. 有谁知道为什么这种行为遵循语言?
  2. 更重要的是,谁能提供有关如何修改 Java 中的默认行为以改为遵循该语言的详细信息?

谢谢。

4

8 回答 8

6

很有可能您的系统上没有已知的“en_IT”语言环境,而 Java 也不知道这样的语言环境。

因此,您将获得最接近匹配语言环境的资源,根据JavaDoc 中的Locale此注释:

当您请求特定语言环境的资源时,您会得到最佳可用匹配,不一定正是您所要求的。有关更多信息,请查看ResourceBundle

中的相关文档ResourceBundle表明,从未尝试仅将国家/地区作为标识符来查找给定资源。仅使用语言、语言 + 国家和语言 + 国家 + 变体。

于 2010-02-17T16:42:56.967 回答
4

但是,如果您是居住在意大利的英国人,那么您可能仍然以英语的方式写数字,并在脑海中以英镑为单位数钱-反之亦然;-)

所以对我来说,这种行为看起来完全合乎逻辑。恐怕没有办法得到你想要的:-(

根据 Oscar Reyes 的评论更新:在 Java 6 中,NumberFormatProvider 使您能够实现您的目标。

于 2010-02-17T16:23:36.930 回答
4

1.- 有谁知道为什么这种行为遵循语言?

应用程序根据其语言环境而改变的第一个方面是语言。想想瑞士,他们将法语和德语作为官方语言。在这种情况下使用国家是没有意义的,因为除了货币还有其他方面(例如显示消息,需要考虑)

许多国家也是如此(我想到的是加拿大)。

该国家/地区是专门化该语言的一个选择。

由于没有“意大利语英语”,因此 en_IT 没有多大意义。所以它需要“英语”,这就是为什么返回的实例是带有“en”英语的实例。

2.- 更重要的是,任何人都可以提供有关如何修改 Java 中的默认行为以改为遵循该语言的详细信息吗?

你的意思是,国家对吗?

答案在方法中:NumberFormat.getAvailableLocales()这反过来又会引导您:NumberFormatProvider这是一个抽象类,您可以扩展它以返回正确NumberFormat的“en_IT”(它几乎会返回 it_IT)

如何安装这个新类超出了我的知识范围,但我认为你必须在jre目录中的某个地方破解它。

编辑

因为我怀疑该类应该安装在jre/ext文件夹下,就是这样。

其他地方有一个项目做了类似的事情来支持“gl_ES”(加利西亚语)

以下是有关如何安装它以及它的全部内容的说明:

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

所以,基本上,如果你想为意大利提供一堆实例(或者更好的是一个),你只需要创建一个 NumberFormatProvider 实例并让它响应所有可用的语言。

于 2010-02-17T18:45:18.010 回答
2

Modifying all of Java is a big order; as far as I know, there's no way to do this at the JVM level. However, you can manually set the number format for your particular classes/projects to pretty much any locale (or even imaginary system) with the DecimalFormatSymbols class. See "Altering the Formatting Symbols" at the Java Tutorials page on format customization for examples and more information.

Granted, this is not an optimal approach if your program might be used in more than three or four different locations, but it could work if you're only supporting a few.

于 2010-02-17T16:37:02.740 回答
2

您的假设“我本以为它会跟随该国家/地区,因为如果我在该国家/地区,无论我说英语还是意大利语,该国家/地区的数字都以小数点分隔符为逗号。” 是错的。一些双语国家/地区具有特定于语言的数字格式规则。在 Sun 的 JDK 中有格式规则的国家中,这适用于加拿大、印度和卢森堡。

于 2010-02-17T17:15:08.377 回答
0

I think you might be able to override the NumberFormat behavior per Locale using LocaleServiceProvider. This would require Java 6 though ...

于 2010-02-17T16:36:48.643 回答
0

正如人们所指出的那样,问题很可能是java找不到您的确切本地,所以它去了它认为最接近的地方。如果您确实有 DecimalFormat 对象,则可以根据需要手动更改分隔符。

DecimalFormat format = ...;
DecimalFormatSymbols symbols = format.getDecimalFormatSymbols();
symbols.setDecimalSeparator(',');
symbols.setGroupingSeparator('.');
format.setDecimalFormatSymbols(symbols);
于 2012-07-24T19:24:29.797 回答
0

我原以为它会跟随这个国家,因为如果我在这个国家,无论我说英语还是意大利语,那个国家的数字都是用逗号分隔的小数点。

不可以。某些拥有多种官方语言的国家/地区,例如加拿大(两种官方语言)根据语言有不同的格式约定:

-1 234,56 (Locale.CANADA_FRENCH)
-1,234.56 (Locale.CANADA (should probably be named CANADA_ENGLISH))
于 2012-07-24T14:34:48.593 回答