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

5us2dqdw  于 2021-06-30  发布在  Java
关注(0)|答案(2)|浏览(394)

如何使用不支持的区域设置(例如。 ar-US )在Java11中,当我通过 String.format() ?
在Java8中,这很好(请尝试jdoodle,选择JDK1.8.0\u66):

Locale locale = Locale.forLanguageTag("ar-US");
System.out.println(String.format(locale, "Output: %d", 120));
// Output: 120

因为java 11,所以输出是东方阿拉伯数字(试试jdoodle,使用默认的jdk 11.0.4):

Locale locale = Locale.forLanguageTag("ar-US");
System.out.println(String.format(locale, "Output: %d", 120));
// Output: ١٢٠

似乎,这个问题来自于语言环境数据提供者从jre到cldr的转换(来源:java9中的本地化更改,作者@mcarth)。下面是支持的区域设置列表:jdk 11支持的区域设置
更新
我将问题示例更新为 ar-US ,就像我之前的例子一样没有意义。我们的想法是要有一个在特定国家有意义的格式。例如美国( US ).

sqougxex

sqougxex1#

该行为符合被视为首选的cldr Locale . 为了证实这一点,可以使用

-Djava.locale.providers=CLDR

如果返回查看jep 252:默认情况下使用cldr区域设置数据,详细信息如下:
默认的查找顺序是cldr、compat、spi,其中compat指定jre在jdk9中的语言环境数据。如果某个特定提供程序无法提供所请求的区域设置数据,则搜索将按顺序转到下一个提供程序。
因此,简而言之,如果您真的不希望默认行为是java-11的行为,那么可以使用vm参数更改查找顺序

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

可能有助于进一步了解如何使用cldr选择正确的语言!

mm9b1k5b

mm9b1k5b2#

我肯定我漏掉了一些细微的差别,但问题是你的标签,所以修复它。明确地: ar-EN 毫无意义。简称:

language = arabic
country = ?? nobody knows.

英国不是一个国家。 en 当然是一个语言代码(对于英语),但是语言标签的第二部分代表国家,而en不是国家(就上下文而言,有 en-GB 英国英语和 en-US 美国英语)。
因此,这和 ar (例如,语言=阿拉伯语,与任何特定国家无关)。即使你把它和某个国家联系在一起,这在这里也是无关紧要的;这会影响到诸如“一周的第一天是什么”、“假定使用哪种货币符号”以及“温度应该用开尔文或华氏度来表示”之类的事情。它与如何显示数字无关,因为这都是基于语言的。
语言是阿拉伯语,١٢٠ 是你尝试时得到的 ar 当打印数字120时作为语言标记。问题是你希望这种情况再次出现 "120" 这是一个奇怪的想法,不幸的是,java在很长一段时间内都带有一个bug,使得它以这种奇怪的方式运行,认为用阿拉伯语呈现数字120最好用 "120" ,这是错误的。
因此,在这种情况下,按照优先顺序:

最佳解决方案

找出为什么你的系统最终以ar en结束,但仍然需要'120',并解决这个问题。一般也固定ar en;英国不是一个国家。
一般来说,“unsupported locale”并不是什么东西。这个 ar 部分是受支持的,它是标记中唯一用于呈现数字的相关部分。

替代品

如果上述方法不可行,最有可能的最佳答案是明确地解决它。自己检测标记,并编写代码,只响应使用 Locale.ENGLISH 相反,保证你得到 Output: 120 . 剩下的情况似乎更糟:您可以尝试编写一个本地化提供程序,这是一项繁重的工作,或者您可以尝试告诉java使用该提供程序的jre版本,但该版本已经过时,不会更新,因此您正在将can踢下道路,并为以后的维护负担做好准备。
1.)考虑到jre变体实际上打印了120,而且你也表示你想要这个,我有一种烦人的感觉,我遗漏了一些政治或历史信息,以及 ar-EN 结果将数字120呈现为 "120" 没那么疯狂。如果你愿意的话,我很想听听这个故事!

相关问题