设置阿拉伯语编号系统区域设置不会显示阿拉伯数字

时间:2015-03-19 20:58:31

标签: java javafx locale javafx-8 arabic

我读过这篇文章:JDK 8 and JRE 8 Supported Locales,它声明:

  

编号系统可以由带有编号系统ID的语言标签指定    ╔═════════════════════╦══════════════════════╦══════════════════╗ ║ Numbering System ID ║ Numbering System ║ Digit Zero Value ║ ╠═════════════════════╬══════════════════════╬══════════════════╣ ║ arab ║ Arabic-Indic Digits ║ \u0660 ║ ╚═════════════════════╩══════════════════════╩══════════════════╝

现在,为了证明这一点,我写了以下代码:

import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.util.Locale;

public class Main
{
    public static void main(String[] args)
    {
        Locale locale = new Locale("ar", "sa", "arab");
        DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(locale);
        NumberFormat numberFormat = NumberFormat.getNumberInstance(locale);
        System.out.println(dfs.getZeroDigit());
        System.out.println(numberFormat.format(123));
    }
}

我期待输出类似于:

  

0
  123

但是,输出如下:

  

0
  123

这样做的主要目的是使JavaFX GUI显示阿拉伯数字而不是英文数字,​​因为它使用默认语言环境(我可以用Locale.setDefault(...)设置它。)

所以我的问题是,如何使用语言环境中的编号系统来显示Java中的本地化数字?那么,是否可以在JavaFX上应用它?

2 个答案:

答案 0 :(得分:17)

是的,我做到了!仔细阅读Locale's JavaDoc之后,我就能够生成所需的语言环境:

Locale arabicLocale = new Locale.Builder().setLanguageTag("ar-SA-u-nu-arab").build();

相当于:

Locale arabicLocale = new Locale.Builder().setLanguage("ar").setRegion("SA")
                   .setExtension(Locale.UNICODE_LOCALE_EXTENSION, "nu-arab").build();

请注意,我正在使用一种名为(Unicode语言环境/语言扩展名)的东西:

  

UTS#35,“Unicode区域设置数据标记语言”定义了可选属性和关键字,以覆盖或优化与区域设置关联的默认行为。关键字由一对密钥和类型表示。

     

使用扩展键“u”(UNICODE_LOCALE_EXTENSION)将关键字映射到BCP 47扩展值。

数字的扩展名为(nu),我使用的值为(arab)。


您可以看到所有扩展密钥here的列表。

答案 1 :(得分:0)

虽然接受的答案中的LocaleNumberFormat很好地工作,但DateTimeFormatter(以及其他所有java.time格式器)至少在localizedBy()在JDK 10中的引入。

因此对于无法使用JDK 10+并希望获得日期的完全本地化字符串表示的人们,一种替代方法是(Kotlin):

// code in the oh-so-sweet-and-sugary Kotlin
val locale = Locale.Builder()
                   .setLanguageTag("ar-SA-u-nu-arab")
                   .build()
val numFormat = NumberFormat.getNumberInstance(locale)
val formatter = DateTimeFormatter.ofPattern("yyyy MM dd", locale)
val str = formatter.format(OffsetDateTime.now())
// String.replace(Regex, noninline (MatchResult) -> CharSequence)
str.replace(Regex("\\d"), {numFormat.format(it.value.toInt())})) // this method is gold
println(str)

我觉得可以用更好/更优雅的方式来做到这一点。如果有人有,请分享。