У меня есть простой EditText
, который позволяет пользователю вводить число, например 45.60
(например, для американского доллара). Затем я форматирую это число, используя следующий метод:
public String format() {
NumberFormat formatter = NumberFormat.getCurrencyInstance(Locale.getDefault());
return formatter.format(amount.doubleValue());
}
А на моем телефоне Android установлен английский (США) язык, поэтому Locale.getDefault()
должен возвращать локаль США (и это так).
Теперь текст редактирования правильно обновлен до: $45.60
(следовательно, форматирование введенного числа работает).
Однако, если я попытаюсь проанализировать указанную выше String "$45.60"
, используя следующий метод:
NumberFormat numberFormat = NumberFormat.getInstance(Locale.getDefault());
Number result = numberFormat.parse("$45.60");
Это не работает с:
java.lang.IllegalArgumentException: Failed to parse amount $45.60 using locale en_US.
Если я настроил свой телефон на английский / британский язык, форматирование этого "45.60"
на "£45.60"
будет работать правильно (как для США), однако синтаксический анализ "£45.60"
завершится неудачно, как и в приведенном выше примере для США.
Однако, если я настроил свой телефон на немецкий язык (Германия), форматирование "45,60"
на "45,60€"
будет работать правильно, И синтаксический анализ "45,60€"
также будет работать правильно!
Единственная разница, которую я вижу между этими тремя валютами: евро добавляется к сумме, а доллар и фунт добавляются к сумме.
Кто-нибудь знает, почему один и тот же код работает для евро, но не для фунта и доллара? Я что-то упускаю?
Я также создал модульный тест, чтобы воспроизвести проблему:
public void testCreateStringBased() throws Exception {
// For German locale
CurrencyAmount amount = new CurrencyAmount("25,46€", Locale.GERMANY);
assertEquals(25.46, amount.getAsDouble());
// For French locale
amount = new CurrencyAmount("25,46€", Locale.FRANCE);
assertEquals(25.46, amount.getAsDouble());
// For US locale
amount = new CurrencyAmount("$25.46", Locale.US);
assertEquals(25.46, amount.getAsDouble());
// For UK locale
amount = new CurrencyAmount("£25.46", Locale.UK);
assertEquals(25.46, amount.getAsDouble());
}
CurrencyAmount
в основном обертывает опубликованный мной код для синтаксического анализа строк валюты, за исключением того, что он принимает заданный языковой стандарт вместо языкового стандарта по умолчанию. В приведенном выше примере тест проходит успешно для локали ГЕРМАНИЯ и ФРАНЦИЯ, но не проходит для локали США и Великобритании.