В Java форматирование числа в соответствии с форматом валюты для конкретной локали довольно просто. Вы используете экземпляр класса java.text.NumberFormat, создав его экземпляр с помощью NumberFormat.getCurrencyInstance () и вызывая один из методов format () . Ниже приведен фрагмент кода из https://docs.oracle.com/javase/tutorial/i18n/format/numberFormat.html.
static public void displayCurrency( Locale currentLocale) {
Double currencyAmount = new Double(9876543.21);
Currency currentCurrency = Currency.getInstance(currentLocale);
NumberFormat currencyFormatter =
NumberFormat.getCurrencyInstance(currentLocale);
System.out.println(
currentLocale.getDisplayName() + ", " +
currentCurrency.getDisplayName() + ": " +
currencyFormatter.format(currencyAmount));
}
Однако, если приложение позволяет пользователям вводить сумму в виде строки с использованием разделителей и символов валюты, вполне возможно, что формат валюты может не соблюдаться в зависимости от локали. Например, пользователь может использовать неправильный разделитель тысяч или десятичный разделитель или неверный символ валюты в целом.
В этом случае приложение должно включать механизм, обеспечивающий сначала соблюдение этого формата, а затем анализ этой строки, чтобы преобразовать ее в правильное число, чтобы выполнить несколько математических вычислений независимо от формата валюты.
Это важно отметить , что разбор строки с использованием java.text.NumberFormat # общедоступного номер разобраны (источник String) метод требует, чтобы строка валюты должна содержать значение по образцу локалей , определенные в java.text.DecimalFormat и символы , определенные в java.text.DecimalFormatSymbols . Если шаблон и / или символы не соблюдаются, программа выдаст исключение java.text.ParseException . Например, шаблон валюты для it_CH = итальянский (Швейцария) равен ¤ #, ## 0,00, а разделитель группировки — ‘ , следовательно, SFr. 1’234,56 действует, а 1 234,56 SFr. является недействительным
Для проверки действительности суммы валюты перед ее фактическим анализом очень удобен проект org.apache.commons.validator.routines.CurrencyValidator проекта Apache Commons Validator . Все, что вам нужно сделать, — это создать его объект и вызвать публичный логический метод isValid (String value, Locale locale), чтобы проверить, соблюдается ли специфичный для локали формат или нет.
Как только вы закончите проверку и обнаружите, что номер является действительным, вы можете затем проанализировать номер, вызвав метод parse (). Следующий фрагмент кода показывает, как проверить и проанализировать. Обратите внимание, что проверка мягкая и если символ валюты еще не присутствует в строке, он добавляет соответствующий символ валюты в соответствии с шаблоном, а затем проверяет и анализирует его.
/**
* Converts given item price into a number based on given
* currency code.
* <p>
* It works generically for all currencies supported by Java
* </p>
*
* @param itemPrice currency amount
* @param currencyCode 3-letter ISO country code
* @return {@link String} containing stripped price or same as given price
* if parsing failed or formatter couldn't be constructed
* @author Muhammad Haris
*/
public static Double convertPrice(String itemPrice, String currencyCode) {
Double itemPriceConverted = null;
Locale currencyLocale = LocaleUtility
.getLocaleAgainstCurrency(currencyCode);
DecimalFormat currencyFormatter = getCurrencyFormatter(currencyLocale);
if (currencyFormatter != null) {
itemPrice = appendCurrencySymbol(itemPrice,
currencyFormatter);
try {
Number number = currencyFormatter.parse(itemPrice);
itemPriceConverted = number.doubleValue();
} catch (ParseException e) {
LOG.error("Failed to parse currency: " + currencyCode
+ ", value: " + itemPrice + ". " + e.getMessage(), e);
}
} else {
LOG.error("No appropriate formatter found for currency: "
+ currencyCode + ", value: " + itemPrice + ". ");
}
return itemPriceConverted;
}
/**
* Gets currency formatter against given currency locale
*
* @param currencyCode
* {@link String} containing 3 letter ISO currency code
* @return {@link NumberFormat} object specialized for the currency or null
* if it couldn't be composed
* @author Muhammad Haris
*/
public static DecimalFormat getCurrencyFormatter(Locale currencyLocale) {
if (currencyLocale != null) {
return (DecimalFormat) NumberFormat
.getCurrencyInstance(currencyLocale);
}
return null;
}
/**
* Appends appropriate currency symbol to the given price using the pattern
* defined in the given currency formatter
*
* @param itemPrice
* {@link String} containing price of the item in locale specific
* format
* @param currencyFormatter
* {@link DecimalFormat} object containing currency locale
* specific formatting info
* @author Muhammad Haris
*/
public static String appendCurrencySymbol(String itemPrice,
DecimalFormat currencyFormatter) {
String currencySymbol = currencyFormatter.getDecimalFormatSymbols()
.getCurrencySymbol();
String pattern = currencyFormatter.toPattern();
if (!itemPrice.contains(currencySymbol)) {
if (pattern.startsWith("¤ ")) {
itemPrice = currencySymbol + " " + itemPrice;
} else if (pattern.endsWith(" ¤")) {
itemPrice = itemPrice + " " + currencySymbol;
} else if (pattern.startsWith("¤")) {
itemPrice = currencySymbol + itemPrice;
} else if (pattern.endsWith("¤")) {
itemPrice = itemPrice + currencySymbol;
}
}
return itemPrice;
}