如何在Java11中使用不支持的语言环境和String.format()中的数字

如何在Java11中使用不支持的语言环境和String.format()中的数字,java,locale,number-formatting,java-11,cldr,Java,Locale,Number Formatting,Java 11,Cldr,当我通过String.format()输出数字时,如何在Java11中使用不受支持的区域设置(例如ar US) 在Java8中,这很好(请尝试,选择JDK1.8.066): Locale=Locale.forLanguageTag(“ar US”); System.out.println(String.format(区域设置,“输出:%d”,120)); //产出:120 由于Java11输出在(请尝试,使用默认的JDK11.0.4): Locale=Locale.forLanguageTag

当我通过
String.format()
输出数字时,如何在Java11中使用不受支持的区域设置(例如
ar US

Java8中,这很好(请尝试,选择JDK1.8.066):

Locale=Locale.forLanguageTag(“ar US”);
System.out.println(String.format(区域设置,“输出:%d”,120));
//产出:120
由于Java11输出在(请尝试,使用默认的JDK11.0.4):

Locale=Locale.forLanguageTag(“ar US”);
System.out.println(String.format(区域设置,“输出:%d”,120));
//输出:١٢٠
这个问题似乎来自于区域设置数据提供程序表单JRE的切换(来源:)。以下是受支持的区域设置列表:

更新


我将问题示例更新为
ar US
,因为我之前的示例没有意义。这个想法是要有一个在特定国家有意义的格式。在本例中,它将是美国(
US
)。

我确信我遗漏了一些细微差别,但问题在于您的标签,所以请修复它。具体而言:

ar-EN
毫无意义。这是:

language = arabic
country = ?? nobody knows.
英国不是一个国家
en
当然是一种语言代码(英语),但语言标签中的第二部分是国家代码,而en不是国家代码。(对于上下文,英式英语有
en-GB
,美式英语有
en-US

因此,这与
ar
(比如,语言=阿拉伯语,与任何特定国家无关)。即使你把它和某个国家联系在一起,这在这里基本上是无关紧要的;这将影响到诸如“一周的第一天是什么”、“假定使用哪种货币符号”以及“温度是否应该以开尔文或华氏度表示”之类的事情。它与如何显示数字无关,因为这都是基于语言的

而且语言是阿拉伯语,因此,当您在打印数字120时尝试将
ar
作为语言标记时,会得到£٠٠。问题是,您希望它返回
“120”
,这是一个奇怪的愿望1,不幸的是,java很长一段时间都带有一个bug,导致它以这种奇怪的方式运行,认为用阿拉伯语呈现数字120最好用
“120”
,这是错误的

因此,在这种情况下,按照优先顺序:

最佳解决方案 找出为什么您的系统最终使用ar EN,但仍然需要“120”,并修复此问题。一般情况下也要固定ar-EN;英国不是一个国家

更一般地说,“不支持的区域设置”并不是一个真正的问题。支持
ar
部分,它是标记中唯一用于呈现数字的相关部分

选择 如果上述方法不可行,最有可能的最佳答案是明确地解决它。自己检测标记,并编写代码,只响应使用
Locale.ENGLISH
格式化此数字的结果,从而确保获得
输出:120
。剩下的似乎更糟:您可以尝试编写一个本地化提供程序,这是一项繁重的工作,或者您可以尝试告诉java使用该提供程序的JRE版本,但该版本已经过时,将不会更新,因此您正在继续努力,并为以后的维护负担做好准备


1.)考虑到JRE变体实际上打印了120,并且你也表示你想要这个,我有一种唠叨的感觉,我遗漏了一些政治或历史信息,并且期望
ar EN
将数字120呈现为
“120”
并不是那么疯狂。如果你愿意的话,我很想听听这个故事

该行为符合被视为首选
区域设置的CLDR。为了证实这一点,可以使用

-Djava.locale.providers=CLDR
如果您后退一步查看,详细信息如下:

默认的查找顺序为CLDR、COMPAT、SPI,其中COMPAT 在JDK 9中指定JRE的区域设置数据。如果某个提供商 无法提供请求的区域设置数据,搜索将继续到 下一个提供者

因此,简而言之,如果您确实不希望默认行为是Java-11的行为,那么可以使用VM参数更改查找顺序

-Djava.locale.providers=COMPAT,CLDR,SPI

可能有助于进一步了解您的目标是什么?
ar EN
是什么意思<代码>EN
不可用。您想描述什么语言环境?您能更好地描述“使用不受支持的语言环境”的含义吗@rzwitserloot已经描述了正在发生的事情,但是为了解决您的问题,我们需要知道您实际想要实现的目标。@JoachimSauer by unsupported Locale我的意思是不包含在“Supported Locale”列表()中。很抱歉这个坏例子,我将问题更新为
ar-US
@wittich试试这个:
Locale.forLanguageTag(“ar-US-u-nu-latn”)
@wittich嗯,是的,这就是从JRE到CLDR的转换。在不更改代码/标记的情况下,您唯一可以进行的真正“修复”是更改提供程序,但这是一个死胡同(JRE列表不再更新)。语言标记如何成为问题?我认为,这个问题的更新确实违背了这方面的任何暗示。此外,即使您使用
ar EN
的标记,代码也会按照问题中OP的说明执行。在CLDR模型中,“将此数值呈现为字符串”作业基本上是语言的一个方面,与国家有关(与“一周的第一天是星期天还是星期一?”形成对比,后者100%基于国家而非语言)。这就解释了为什么
-US
部分不能也不能用于更改语言环境设置的功能。因此,仅
ar
是相关的,但这是不够的,因为没有进一步上下文的“阿拉伯语”具有多重含义