Convert different countries' currencies to dual use java

I have a scenario where in I I get the currency as a string, for example:

$ 199.00

R $ 399.00

£ 25.00

90,83 €

AED 449.00

How to convert these currencies to double in java?

+8
java currency
source share
4 answers

Never use double to represent exact values

Well of course you can do it, but you need to really understand floating point arithmetic

Use NumberFormat . Although it handles some currencies, it is usually simpler to simply delete all currency symbols. NumberFormat will use Locale to determine the delimiters to use:

 public static BigDecimal parse(final String amount, final Locale locale) throws ParseException { final NumberFormat format = NumberFormat.getNumberInstance(locale); if (format instanceof DecimalFormat) { ((DecimalFormat) format).setParseBigDecimal(true); } return (BigDecimal) format.parse(amount.replaceAll("[^\\d.,]","")); } 

This takes a String from the sum and Locale . He then creates an instance of the BigDecimal NumberFormat . It uses replaceAll and regex to remove all digits, not digits . and , from among, then analyzes it.

A quick demonstration of your examples:

 public static void main(String[] args) throws ParseException { final String dollarsA = "$199.00"; final String real = "R$ 399,00"; final String dollarsB = "£25.00"; final String tailingEuro = "90,83 €"; final String dollarsC = "$199.00"; final String dirham = "AED 449.00"; System.out.println(parse(dollarsA, Locale.US)); System.out.println(parse(real, Locale.FRANCE)); System.out.println(parse(dollarsB, Locale.US)); System.out.println(parse(tailingEuro, Locale.FRANCE)); System.out.println(parse(dollarsC, Locale.US)); System.out.println(parse(dirham, Locale.US)); } 

Output:

 199.00 399.00 25.00 90.83 199.00 449.00 

I just used US , where is the decimal number . and FRANCE , where is the decimal number , but you can use the correct Locale for the currency if you want.

+12
source share

As David Wallace said, you did not do this (or if you do, you do it very carefully and only if you are deeply informed about the problems), because double usually not suitable for use with currency values. It has issues like 0.1 + 0.2 ending in 0.30000000000000004 (and others). Used correctly , BigDecimal is probably better suited, although much slower. (More on how to "use it right" below.)

First, you must determine that thousands and decimal separators are used, from the locale ( see Boris for an excellent answer for this) or the information is provided along with the string. In some cultures, they , (thousand) And . (decimal), for example. "1,000.24", but in other cultures it is the other way around (for example, "1.000, 24"). As far as I know, in some places other symbols are used. (You cannot guess this from the line; you do not know if "1,234" means one thousand two hundred thirty-four or one point two three four.)

Once you know what it is, you want to remove the thousands separators, convert the decimal place to . (in particular), and then remove from the line all non-digital, non-minus, non-decimal numbers:

 // where `currencyString` is the string containing the currency currencyString = currencyString .replace(thousandsString, "") .replace(decimalString, ".") .replaceAll("[^\\d.-]", ""); 

Then create your BigDecimal :

 BigDecimal currency = new BigDecimal(currencyString); 

... and set the scaling and rounding mode to suit your program. Also be sure to carefully read the Javadoc for various working methods. For example, as Peter Laurie noted in the comments, naive use of BigDecimal will give you runtime exceptions:

 BigDecimal bd = new BigDecimal(43); bd = bd.divide(new BigDecimal(7)); // Throws ArithmeticException 

You can handle them by providing rounding information:

 BigDecimal bd = new BigDecimal(43); bd = bd.divide(new BigDecimal(7), RoundingMode.HALF_UP); 

... but again, be sure to set the scale to what you are doing. For example, if your scale is 2 , then (43 / 7) * 7 RoundingMode.HALF_UP (43 / 7) * 7 with RoundingMode.HALF_UP will be 42.98 instead of 43 . Separation is especially difficult, you may need a significant scale, and then final rounding off to more normal currency level scales (usually 2, but sometimes you may need more seats on the right).


If you really really want a double , use Double.parseDouble :

 // where `currencyString` is the string containing the currency currencyString = currencyString .replace(thousandsString, "") .replace(decimalString, ".") .replaceAll("[^\\d.-]", ""); double thisWillHaveIssues = Double.parseDouble(currencyString); 
+3
source share

Usage contains, replace and valueOf

 if(line.constains("$")){ double value=Double.valueOf(line.replace("$","")); } if(line.constains("£")){ double value=Double.valueOf(line.replace("£","")); } //same with others 
0
source share

An easier way is to use DecimalFormal, as in the following example:

 String myMoney = 90,83String s try { s = DecimalFormat.getCurrencyInstance(Locale.getDefault()).parse (myMoney).toString() } catch (ParseException e) { return; } double d = Double.parseDouble(s); 
0
source share

All Articles