Интернационализация. Форматирование числовых значений.

Ранее упоминалось, что в разных странах и регионах используются различные способы представления чисел и денежных сумм. В пакетах java.text содержатся классы, позволяющие форматировать числа и выполнять разбор их строкового представления. Для форматирования чисел в соответствии с конкретным региональным стандартом необходимо выполнить ряд действий:
  1. Получить объект регионального стандарта, как было описано в предыдущем разделе.
  2. Использовать фабричный метод для получения объекта форматирования.
  3. Применить полученный объект форматирования для формирования числа или разбора его строкового представления.
Здесь в качестве фабричных методов (factory method) используются статические методы getNumberInstance (), getCurrencyInstance (), getPercentInstance () класса NumberFormat. Они получают в качестве параметра объект Locale и возвращают объекты, предназначенные для форматирования чисел, денежных сумм и значений, выраженных в процентах. Например, для отображения денежной суммы в формате, принятом в Германии, можно использовать приведенный ниже фрагмент кода:
  
  Locale loc = new Locale ("de", "DE");
  NumberFormat currFmt = NumberFormat.getCurrencyInstance (loc);
  double amt = 123456.78;
  System.out.println (currFmt.format (amt));

В результате выполнения этого кода будет получена следующая строка:

123.456,78 DM

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

Для преобразования строки, записанной в соответствии с определенным региональным стандартом, в число предусмотрен метод parse (), который выполняет синтаксический анализ строки с автоматическим использованием заданного по умолчанию регионального стандарта. В приведенном ниже примере показан способ преобразования строки, введеной пользователем в поле редактирования, в число. Метод parse () способен преобразовывать числа, в которых в качестве разделителя используется точка и запятые.

  TextField inputField; 
  . . . 
  NumberFormat fmt = NumberFormat.getNumberInstance (); 
  
  // Получить объект форматирования для используемого 
  // по умолчанию регионального стандарта 
  
  Number input = fmt.parse (inputField.getText ().trim ()); 
  double x = input.doubleValue (); 

Метод parse () возвращает результат абстрактного типа Number. На самом деле возвращаемый объект является экземпляром класса Long или Double, в зависимости от того, представляет исходная строка целое число или число с плавающей точкой. Если это не важно, то для получения числового значения достаточно использовать метод doubleValue() класса Number.
Для объектов типа Number не поддерживается автоматическое приведение к простым типам. Необходимо явным образом вызывать метод doubleValue () или intValue ().

Если число представлено в некорректном формате, генерируется исключение ParseException. Например, не допускается наличие символа пробела в начале строки, преобразуемой в число. (Для их удаления следует использовать метод trim ()). Любые символы, которые располагаются в строке после числа, лишь игнорируются и исключение в этом случае не возникает.

Очевидно, что классы, возвращаемые методами getXxxInstance (), являются экземплярами не абстрактного класса NumberFormat, а одного из его подклассов. Фабричным методам известно лишь то, как найти объект, представляющий определенный региональный стандарт.

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

Методы пакета java.text.NumberFormat

МетодОписание
static Locale[] getAvailableLocales () Возвращает массив объектов Locale, для которых доступны объекты форматирования
static NumberFormat getNumberFormatInstance ()
static NumberFormat getNumberFormatInstance (Locale l)
static NumberFormat getNumberCurrency ()
static NumberFormat getNumberCurrencyInstance (Locale l)
static NumberFormat getNumberPercent ()
static NumberFormat getNumberPercentInstance (Locale l)
Возвращает объект форматирования чисел, денежных сумм или величин, представленных в процентах, для текущего или заданного регионального стандарта
String format (double x)
String format (long x)
Возвращает строку, полученную в результате форматирования заданного числа с плавающей точкой или целого числа.
Number parse (String s) Возвращает число, полученное после преобразования строки. Это число может иметь тип Long или Double. Строка не должна начинаться с пробелов. Любые символы в строке после числа игнорируются. Если преобразование закончилось неудачей, то метод генерирует исключение ParseException
void setParseIntegerOnly (boolean b)
boolean isParseIntegerOnly ()
Устанавливает или возвращает признак того, что данный объект форматирования предназначен для преобразования только целочисленных значений.
void setGroupingUsed (boolean b)
boolean isGroupingUsed ()
Устанавливает или возвращает флаг, указывающий на то, что данный объект форматирования распознает символы разделения групп десятичных разрядов (например, 100, 000)
void setMinimumIntegerDigits (int n)
void setMaximumIntegerDigits (int n)
void setMinimumFractionDigits (int n)
void setMaximumFractionDigits (int n)
int getMinimumIntegerDigits ()
int getMaximumIntegerDigits ()
int getMinimumFractionDigits ()
int getMaximumFractionDigits ()
Устанавливает или возвращает максимальное либо минимальное количество цифр в целой или дробной части числа

Денежные суммы

Для форматирования денежных сумм используется метод NumberFormat.getCurrencyInstance (). Однако этот метод не обеспечивает достаточной гибкости - он возвращает форматированную строку для одной валюты. Допустим, Вы выписываете счет для американского потребителя, в котором одни суммы представлены в долларах, а другие в евро. Использование двух приведенных ниже объектов форматирования не является решением задачи.

  NumberFormat dollarFormatter = NumberFormat.getCurrencyInstance (Locale.US);
  NumberFormat euroFormatter = NumberFormat.getCurrencyInstance (Locale.GERMANY);

Счет, содержащий такие значения, как $100,000 и 100.000eur, будет выглядеть достаточно странно, поскольку символы разделителей групп разрядов отличаются.

Для управления форматированием денежных сумм следует использовать класс Currency.Для получения объекта Currency необходимо передать статическому методу Currency.getInstance () идентификатор валюты. Затем необходимо вызвать метод setCurrency () каждого объекта форматирования. Ниже показано, как настроить объект форматирования евро для американсого потребителя.

  NumberFormat euroFormatter = NumberFormat.getCurrencyInstance (Locale.US);
  euroFormatter.setCurrency (Currency.getInstance ("EUR"));

Идентификаторы валют определены стандартом ISO 4217 (http://en.wikipedia.org.wiki/ISO_4217). Некоторые из них приведены в таблице.
Наименование валютыОбозначение
Доллар США USD
Евро EUR
Английский фунт GBR
Японская йена JPY
Индийская рупия INR
Российская рупияRUB

Методы пакета java.util.Currency

МетодОписание
static Currency getInstance (String currencyCode)
static Currency getInstance (Locale locale)
Возвращает экземпляр класса Currency, соответствующий заданному коду ISO 4217 или стране, указанной посредством объекта Locale
String toString ()
String getCurrencyCode ()
Возвращает код ISO 4217 для данной валюты
String getSymbol ()
String getSymbol (Locale locale)
Возвращает символ, обозначающий данную валюту в соответствии или заданными региональными настройками. Например, в зависимости от объекта Locale, доллар США (USD) может обозначаться как $ или US$
int getDefaultFractionDigits () Возвращает число цифр в дробной части для данной валюты, принятое по умолчанию