使用java将不同的国家货币转换为双倍
我有一个场景,我把货币作为一个字符串,例如:
$ 199.00
R $ 399,00
£25.00
90,83€
AED 449.00
如何在java中将这些货币转换为双倍?
切勿使用double
来表示确切的金额
当然,你可以这样做,但你需要真正理解浮点运算
使用NumberFormat
。 虽然它确实处理了一些货币,但通常更容易剥离所有货币符号。 NumberFormat
将使用Locale
来计算要使用的分隔符:
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.,]","")); }
这需要一个数量的String
和Locale
。 然后它创建一个BigDecimal
解析NumberFormat
实例。 它使用replaceAll
和regex replaceAll
除数字之外的所有数字.
然后,
从数字然后解析它。
针对您的示例的快速演示:
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)); }
输出:
199.00 399.00 25.00 90.83 199.00 449.00
我只是使用US
,小数是.
和小数是的FRANCE
,
但如果您愿意,
可以使用正确的货币Locale
。
正如大卫华莱士所说,你没有(或者如果你这样做,你只是在非常仔细地了解问题的情况下这样做),因为double
通常不适合与货币价值一起使用。 它有像0.1 + 0.2
这样的问题最终为0.30000000000000004
(和其他此类)。 正确使用 BigDecimal
可能更适合,但速度要慢得多。 (更多关于“正常使用”的信息。)
首先,你必须确定所使用的千位和小数分隔符是什么,来自语言环境( 请参阅Boris的优秀答案 )或者提供与字符串一起提供的信息。 在某些文化中,它们是(数千)和.
(十进制),例如“1,000.24”,但在其他文化中则是另一种方式(例如,“1.000,24”)。 据我所知,在某些地方还有其他字符。 (你无法从字符串中猜出这一点,你不知道"1,234"
是指一千二百三十四还是一点二三四。)
一旦你知道它们是什么,你想删除千位分隔符,将小数转换为.
(具体而言),然后从字符串中删除所有非数字,非减号,非小数:
// where `currencyString` is the string containing the currency currencyString = currencyString .replace(thousandsString, "") .replace(decimalString, ".") .replaceAll("[^\\d.-]", "");
然后构造你的BigDecimal
:
BigDecimal currency = new BigDecimal(currencyString);
…并设置适合您的程序的比例和舍入模式 。 另外请务必仔细阅读Javadoc以了解各种操作方法。 例如,正如Peter Lawrey在评论中指出的那样,天真地使用BigDecimal
会给你运行时exception:
BigDecimal bd = new BigDecimal(43); bd = bd.divide(new BigDecimal(7)); // Throws ArithmeticException
您可以通过提供舍入信息来处理这些信息:
BigDecimal bd = new BigDecimal(43); bd = bd.divide(new BigDecimal(7), RoundingMode.HALF_UP);
……但是,请务必设置适合您正在做的事情的比例。 例如,如果您的比例仅为2
,则RoundingMode.HALF_UP
42.98
(43 / 7) * 7
将为42.98
而不是43
。 划分特别棘手,您可能需要大规模,然后最终回合到更正常的货币级别比例(通常为2,但有时您可能需要更多的位置到右边)。
如果你真的,真的,真的想要一个double
,请使用Double.parseDouble
:
// where `currencyString` is the string containing the currency currencyString = currencyString .replace(thousandsString, "") .replace(decimalString, ".") .replaceAll("[^\\d.-]", ""); double thisWillHaveIssues = Double.parseDouble(currencyString);
使用contains,replace和valueOf
if(line.constains("$")){ double value=Double.valueOf(line.replace("$","")); } if(line.constains("£")){ double value=Double.valueOf(line.replace("£","")); } //same with others
更简单的方法是使用DecimalFormal,如下例所示:
String myMoney = 90,83 € String s try { s = DecimalFormat.getCurrencyInstance(Locale.getDefault()).parse (myMoney).toString() } catch (ParseException e) { return; } double d = Double.parseDouble(s);