Подтвердить что ты не робот

Получить формат номера из ОС

Этот вопрос кажется безумно простым, но я смущен, сказав, что мне не удалось выяснить, как это работает.

Я хочу, чтобы мое приложение Java SE получало свой формат номера от того, что настроено в ОС. Как и любое другое приложение на этой ОС.

Моя цель - в первую очередь Windows. Рассмотрим этот пример в Windows:

enter image description here

Я использую этот маленький пример, чтобы проверить результат:

public class MyMain {
    public static void main(String[] args) {
        DecimalFormat decFormat = new DecimalFormat();
        DecimalFormatSymbols decSymbols = decFormat.getDecimalFormatSymbols();           
        System.out.println("Decimal separator is : " + decSymbols.getDecimalSeparator());
        System.out.println("Thousands separator is : " + decSymbols.getGroupingSeparator());
    }
}

С примером скриншота выше моего маленького примера Java prints:

Decimal separator is : ,
Thousands separator is : .

Я бы ожидал, что он скажет, что десятичный разделитель является точкой, а тысячи разделитель - это запятая, потому что это то, что я сказал Windows, и что все остальные приложения Windows забирают.

У меня создается впечатление, что в Windows эти настройки вступают в силу для новых процессов. Я попытался перезапустить мою среду IDE. Не помогло.

Что я делаю неправильно?

4b9b3361

Ответ 1

Я сам нашел ответ.

Начиная с JDK8 вы можете попросить Java иметь настройки хоста в качестве приоритета номер один при разрешении материала, связанного с локалью.

Я немного расширил свой пример:

public class MyMain {
    public static void main(String[] args) {
        DecimalFormat decFormat = new DecimalFormat();
        DecimalFormatSymbols decSymbols = decFormat.getDecimalFormatSymbols();
        String localeProvidersList = System.getProperty("java.locale.providers", "JRE,SPI");
        System.out.println("Decimal separator is : " + decSymbols.getDecimalSeparator());
        System.out.println("Thousands separator is : " + decSymbols.getGroupingSeparator());
        System.out.println("Locale providers list : " + localeProvidersList);
    }
}

Запуск моего примера выше с помощью -Djava.locale.providers=HOST,JRE,SPI дает:

Decimal separator is : .
Thousands separator is : ,
Locale providers list : HOST,JRE,SPI

Выполнение без java.locale.providers дает:

Decimal separator is : ,
Thousands separator is : .
Locale providers list : JRE,SPI

Лично я всегда буду запускать свои Java-приложения с помощью -Djava.locale.providers=HOST,...., потому что это заставит мои приложения Java вести себя как собственное приложение на том же хосте.

Я нашел ответ в глубине javadocs JDK8. Там также несколько примечаний об этом в документах Java 8 Enhancements.

Ответ 2

Вам нужно увидеть: как определить язык операционной системы (языковой стандарт) из java-кода. Похоже, что ошибка была введена в ранних версиях Java 7 и несколько исправлена ​​в более поздней версии Java 7.

Чтобы проверить, я установил свой регион Window 7 на "French France". (То же, что показано на снимке экрана.)

Запуск этого кода:

System.out.println("default locale=" + Locale.getDefault());
System.out.println("user.language=" + System.getProperty("user.language"));
DecimalFormat decFormat = new DecimalFormat();
DecimalFormatSymbols decSymbols = decFormat.getDecimalFormatSymbols();
System.out.println("Decimal separator is : " + decSymbols.getDecimalSeparator());

с выходом Java 6 (jdk1.6.0_45):

default locale = fr_FR

user.language = Fr

Десятичный разделитель:

с выходом Java 7 (jdk1.7.0_40):

default locale = en_US

user.language = еп

Десятичный разделитель:

Таким образом, только один десятичный разделитель корректен с Java 7. Одно из возможных различий - это то, что я не изменил свой "Системный язык" с английского (США) на французский (Франция), потому что ему нужен перезапуск. Возможно, это может повлиять на отображение Java 7 для значений Locale и user.language.