В 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; }