Parsing prices with Currency Symbol in Java
Asked Answered
L

2

5

I want to parse a String that i have into a Number. This is the Code that i'm using but not working:

NumberFormat.getCurrencyInstance(Locale.GERMAN).parse("EUR 0,00");

This results in a java.text.ParseException

So i want to match the String into a number, i don't really care about the currency, but it would be nice to have.

I want the following kind of Strings matched:

EUR 0,00 
EUR 1.432,89
$0.00 
$1,123.42 
1,123.42$ 
1,123.42 USD

Sure, there are ways with RegEx, but i think it would be kind of overkill.

Lasala answered 27/3, 2012 at 15:23 Comment(1)
For each string, do you know ahead of time what locale conventions are being used, or are you looking for an algorithm that takes a best guess. For example, something that realizes that the comma in 1,000.52 serves a different role than that in 1.000,52?Abramabramo
B
7

Locale.GERMAN does not seem to have a currency symbol. Locale.GERMANY has the euro symbol as its currency (not the string "EUR"). Notice that blam1 and blam3 below cause parsing exceptions, the CurrencyFormat object only likes blam2.

NumberFormat numberFormat = NumberFormat.getCurrencyInstance(Locale.GERMANY);

System.out.println("75.13 euro: " + numberFormat.format(75.13));

try {
  System.out.println("Parsed blam1: " + numberFormat.parse("EUR 75,11"));
} catch (ParseException exception) {
  System.out.println("Parse Exception1: " + exception);
}

try {
  System.out.println("Parsed blam2: " + numberFormat.parse("75,12 €"));
} catch (ParseException exception) {
  System.out.println("Parse Exception2: " + exception);
}

try {
  System.out.println("Parsed blam3: " + numberFormat.parse("€ 75,13"));
} catch (ParseException exception) {
  System.out.println("Parse Exception3: " + exception);
}

I suspect that you will need to either find an open source currency parser that fits your need or write one yourself.

Bethezel answered 27/3, 2012 at 15:43 Comment(0)
A
0

You stated you think regex is a overkill, but I suppose that for this case it does the job best.

Here's the utility method I wrote to parse the amount and currency from the strings you provided. It returns pair of currency code and amount or null in case it is not able to parse the values:

public static Pair<String, Double> parseCurrencyAndAmount(String amountWithCurrency) {
    Pair<String, Double> result = null;

    Pattern pattern = Pattern.compile("\\d+((.|,)\\d+)((.|,)\\d+)?");
    Matcher matcher = pattern.matcher(amountWithCurrency);
    if (matcher.find()) {
        String amount = matcher.group(0);

        // parse currency code
        String currencyCode = amountWithCurrency.replace(amount, "").trim();

        // parse amount - normalize thousand and decimal separators and keep only decimal as a dot
        amount = amount.replace(",", ".");
        int lastDot = amount.lastIndexOf('.');
        amount = amount.substring(0, lastDot).replace(".","") + amount.substring(lastDot);

        Double parsedAmount = null;
        try {
            parsedAmount = Double.parseDouble(amount);
        }
        catch (Exception ignored) {}

        result = Pair.create(currencyCode, parsedAmount);
    }

    return result;
}
Araucaria answered 17/6, 2022 at 15:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.