Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use unsupported Locale in Java 11 and numbers in String.format()

How can I use an unsupported Locale (eg. ar-US) in JAVA 11 when I output a number via String.format()?

In Java 8 this worked just fine (try jdoodle, select JDK 1.8.0_66):

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

Since Java 11 the output is in Eastern Arabic numerals (try jdoodle, use default JDK 11.0.4):

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

It seems, this problem comes from the switch in the Locale Data Providers form JRE to CLDR (source: Localization Changes in Java 9 by @mcarth). Here is a list of supported locales: JDK 11 Supported Locales

UPDATE

I updated the questions example to ar-US, as my example before didn't make sense. The idea is to have a format which makes sense in that given country. In the example it would be the United States (US).

like image 932
wittich Avatar asked Mar 01 '23 20:03

wittich


1 Answers

The behavior conforms to the CLDR being treated as the preferred Locale. To confirm this, the same snippet in Java-8 could be executed with

-Djava.locale.providers=CLDR

If you step back to look at the JEP 252: Use CLDR Locale Data by Default, the details follow :

The default lookup order will be CLDR, COMPAT, SPI, where COMPAT designates the JRE's locale data in JDK 9. If a particular provider cannot offer the requested locale data, the search will proceed to the next provider in order.

So, in short if you really don't want the default behaviour to be that of Java-11, you can change the order of lookup with the VM argument

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

What might help further is understanding more about picking the right language using CLDR!

like image 121
Naman Avatar answered Mar 05 '23 06:03

Naman