В Java, почему десятичный разделитель следует за языком Локали, не его страной, и, что еще более важно, как каждый переопределяет его?

Я работаю над международным проектом и заметил, что в Java выбор десятичного разделителя основан на языке Локали, не его стране. Например:

DecimalFormat currencyFormatter = (DecimalFormat) NumberFormat.getInstance(new Locale("it","IT"));
System.out.println(currencyFormatter.format(-123456.78));

currencyFormatter = (DecimalFormat) NumberFormat.getInstance(new Locale("en","IT"));
System.out.println(currencyFormatter.format(-123456.78));

производит следующий вывод:

-123.456,78
-123,456.78

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

Мой вопрос является двукратным:

  1. Кто-либо знает, почему это поведение следует за языком?
  2. Что еще более важно, кто-либо может предложить детали относительно того, как изменить поведение по умолчанию в Java для следования за языком вместо этого?

Спасибо.

8
задан Joachim Sauer 17 February 2010 в 16:43
поделиться

6 ответов

1.- Кто-нибудь знает, почему такое поведение следует за языком?

Одним из первых аспектов, которые меняются в приложении в зависимости от его локали, является язык. Подумайте о Швейцарии, где официальными языками являются французский и немецкий. Использование страны в этом сценарии не имеет смысла, потому что, помимо валюты, есть еще один аспект (например, отображаемые сообщения, которые необходимо учитывать)

То же самое касается ряда стран (Канада - другая, которая приходит мне на ум).

Страна - это вариант специализации на этом языке.

Поскольку нет "итальянского английского", en_IT не имеет особого смысла. Итак, он принимает "english", и поэтому возвращаемый экземпляр - это тот, который содержит "en" English.

2.- Что еще более важно, может ли кто-нибудь предложить подробности о том, как изменить поведение по умолчанию в Java, чтобы вместо этого следовать языку?

Вы имеете в виду, страну, верно?

Ответ находится в методе: NumberFormat.getAvailableLocales () , который, в свою очередь, приводит вас к: NumberFormatProvider , который является абстрактным классом, который вы можете расширить, чтобы вернуть правильный NumberFormat для "en_IT" (что в значительной степени вернет it_IT)

Как установить этот новый класс выходит за рамки моих знаний, но я думаю, вам придется взломать его где-нибудь в jre каталог.

РЕДАКТИРОВАТЬ

Как я подозреваю, класс должен быть установлен в папку jre / ext и все.

Где-то еще есть проект, который делал что-то похожее на поддержку "gl_ES" (галисийский язык)

Вот инструкции о том, как его установить и о чем он вообще:

http://www.javagalician.org /install.html

Итак, по сути, если вы хотите предоставить несколько экземпляров для Италии (или даже лучше один), вам просто нужно создать один экземпляр NumberFormatProvider, и он будет отвечать на всех доступных языках.

4
ответ дан 5 December 2019 в 09:25
поделиться

Возможно, есть лучший способ, но я думаю, что n = max - (max - n + 1)% (max + 1) работает. Я предполагаю, что вы хотите включить 0 на обоих концах, так как для вашего инкрементного выражения вы включаете 0.

-121--4268334-

Нет, это никогда не сработает - SQL Server может выполнять резервное копирование только на диск, физически подключенный к фактической машине SQL Server. Вы не можете ни при каких обстоятельствах создать резервную копию удаленного SQL Server на локальном жестком диске - это невозможно (ни в SMO, ни в среде Среда SQL Server Management Studio).

-121--2953988-

Возможно, вы сможете переопределить поведение NumberFormat для каждого языкового стандарта с помощью LocaseServiceProvider . Это потребует Java 6, хотя...

0
ответ дан 5 December 2019 в 09:25
поделиться

Очень, очень вероятно, что в вашей системе нет известной локали "en_IT" и что Java не знает ни одной такой локали.

Поэтому вы получите ресурсы для ближайшей подходящей локали, согласно этому примечанию в JavaDoc по Locale:

Когда вы запрашиваете ресурс для определенной локали, вы получаете в ответ наилучшее доступное соответствие, не обязательно именно то, что вы запрашивали. Для получения дополнительной информации посмотрите ResourceBundle.

В соответствующей документации в ResourceBundle показано, что страна сама по себе никогда не используется в качестве идентификатора для поиска данного ресурса. Используются только язык, язык + страна и язык + страна + вариант.

6
ответ дан 5 December 2019 в 09:25
поделиться

Но если вы англичанин, живущий в Италии, скорее всего, вы все еще пишете свои числа по-английски и в уме считать деньги фунтами - и наоборот; -)

Так что мне такое поведение кажется совершенно логичным. И я боюсь, что может не быть способа получить то, что вы хотите: - (

Обновление на основе комментария Оскара Рейеса: В Java 6 NumberFormatProvider позволяет вам достичь вашей цели.

{{ 1}}
4
ответ дан 5 December 2019 в 09:25
поделиться

Модификация всей Java - это большой заказ; насколько я знаю, нет способа сделать это на уровне JVM. Однако вы можете вручную установить формат чисел для ваших конкретных классов/проектов практически для любой локали (или даже воображаемой системы) с помощью класса DecimalFormatSymbols. Примеры и дополнительную информацию смотрите в разделе "Изменение символов форматирования" на странице Java Tutorials, посвященной настройке форматов.

Конечно, это не оптимальный подход, если ваша программа может использоваться более чем в трех или четырех различных местах, но он может сработать, если вы поддерживаете только несколько.

2
ответ дан 5 December 2019 в 09:25
поделиться

Ваше предположение "Я бы ожидал, что он будет следовать стране, поскольку если я нахожусь в стране, говорю ли я на английском или итальянском, числа в этой стране записываются с десятичным разделителем в виде запятой." неверно. В нескольких двуязычных странах действуют правила форматирования чисел с учетом особенностей языка. Среди стран, имеющих правила форматирования в Sun's JDK, это относится к Канаде, Индии и Люксембургу.

2
ответ дан 5 December 2019 в 09:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: