设置阿拉伯数字系统区域设置不显示阿拉伯数字
Setting Arabic numbering system locale doesn't show Arabic numbers
我读了这篇文章:JDK 8 and JRE 8 Supported Locales,它说:
Numbering systems can be specified by a language tag with a numbering system 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
这样做的主要目的是让 JavaFX GUI 显示阿拉伯数字而不是英语数字,因为它使用默认语言环境(我可以用 Locale.setDefault(...)
设置它)。
所以我的问题是,如何使用语言环境中的编号系统在 Java 中显示本地化数字?那么,是否可以在JavaFX上应用呢?
是的,我做到了!仔细阅读 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 locale/language 扩展名):
UTS#35, "Unicode Locale Data Markup Language" defines optional attributes and keywords to override or refine the default behavior associated with a locale. A keyword is represented by a pair of key and type.
The keywords are mapped to a BCP 47 extension value using the extension key 'u' (UNICODE_LOCALE_EXTENSION).
数字的扩展键是(nu
),我使用的值是(arab
)。
您可以看到所有扩展键的列表here。
虽然已接受答案中的 Locale
与 NumberFormat
配合得很好; DateTimeFormatter
(以及所有其他 java.time
格式化程序)无法正确使用它,至少在 JDK 10.
中引入 localizedBy()
之前是这样
因此,对于无法使用 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)
// this method is gold
str.replace(Regex("\d"), {numFormat.format(it.value.toInt())}))
println(str)
我觉得这可以用 better/more 优雅的方式完成。如果有人有,请分享。
我读了这篇文章:JDK 8 and JRE 8 Supported Locales,它说:
Numbering systems can be specified by a language tag with a numbering system 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
这样做的主要目的是让 JavaFX GUI 显示阿拉伯数字而不是英语数字,因为它使用默认语言环境(我可以用 Locale.setDefault(...)
设置它)。
所以我的问题是,如何使用语言环境中的编号系统在 Java 中显示本地化数字?那么,是否可以在JavaFX上应用呢?
是的,我做到了!仔细阅读 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 locale/language 扩展名):
UTS#35, "Unicode Locale Data Markup Language" defines optional attributes and keywords to override or refine the default behavior associated with a locale. A keyword is represented by a pair of key and type.
The keywords are mapped to a BCP 47 extension value using the extension key 'u' (UNICODE_LOCALE_EXTENSION).
数字的扩展键是(nu
),我使用的值是(arab
)。
您可以看到所有扩展键的列表here。
虽然已接受答案中的 Locale
与 NumberFormat
配合得很好; DateTimeFormatter
(以及所有其他 java.time
格式化程序)无法正确使用它,至少在 JDK 10.
localizedBy()
之前是这样
因此,对于无法使用 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)
// this method is gold
str.replace(Regex("\d"), {numFormat.format(it.value.toInt())}))
println(str)
我觉得这可以用 better/more 优雅的方式完成。如果有人有,请分享。