Проблемы локализации NumberFormat - PullRequest
2 голосов
/ 08 марта 2012

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

English  
1234  
1,234  
1234.56  
1,234.5  

German & Spanish  
1234  
1.234  
1234,56  
1.234,5

French  
1234  
1 234  
1234,56  
1 234,5  

Моя проблема с французским как варианты 2 &4 считаются недействительными при использовании этого кода, так как синтаксический анализ останавливается в пробеле.

public void validate(final FacesContext pContext,
                     final UIComponent pComponent,
                     final Object pValue) {

  boolean isValid = true;
  final Locale locale = (Locale)pComponent.getAttributes().get(USERS_LOCALE);
  final Currency currency = (Currency)pComponent.getAttributes().get(CURRENCY);

  final NumberFormat formatter = NumberFormat.getNumberInstance(locale);
  formatter.setGroupingUsed(true);
  formatter.setMinimumFractionDigits(currency.getDefaultFractionDigits());
  formatter.setMaximumFractionDigits(currency.getDefaultFractionDigits());
  final ParsePosition pos = new ParsePosition(0);
  final String stringValue = (String)pValue;

  if (pos.getIndex() != stringValue.length() || pos.getErrorIndex() != -1) {
    isValid = false;
  }
  ...

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

1 234,9,56 (неверная группировка)
1 234,567(слишком много знаков после запятой для валюты)

Любая помощь будет высоко ценится
Ян

1 Ответ

5 голосов
/ 08 марта 2012

Французский разделитель тысяч фактически является неразрывным пробелом, \u00a0.Если ваш ввод использует обычный пробел, вы можете изменить ввод:

input = input.replace(' ', '\u00a0');

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

DecimalFormat decimalFormatter = (DecimalFormat) formatter;
DecimalFormatSymbols symbols = decimalFormatter.getDecimalFormatSymbols();
symbols.setGroupingSeparator(' ');
decimalFormatter.setDecimalFormatSymbols(symbols);

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

...