使用java将不同国家的货币转换为双倍
我曾经有过一个场景,其中我以字符串的形式获取货币,例如:
$199.00
R$ 399,00
£25.00
90,83 €
迪拉姆 449.00
如何在Java中将这些货币转换为双倍?
我曾经有过一个场景,其中我以字符串的形式获取货币,例如:
$199.00
R$ 399,00
£25.00
90,83 €
迪拉姆 449.00
如何在Java中将这些货币转换为双倍?
切勿使用双精度
来表示确切的金额
好吧,你当然可以做到,但你需要真正理解浮点算术
使用 .虽然它确实处理一些货币,但通常更容易剥离所有货币符号。将用于计算要使用的分隔符: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.,]",""));
}
这需要 a 的量和 .然后,它会创建一个解析实例。它使用 和 regex 去除除数字之外的所有数字,然后从数字中解析它。String
Locale
BigDecimal
NumberFormat
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
正如大卫·华莱士(David Wallace)所说,你不会(或者如果你这样做,你这样做会非常小心,只有在深入了解这些问题的情况下才会这样做),因为通常不适合与货币价值一起使用。它有诸如最终存在(以及其他类似)之类的问题。正确使用的BigDecimal
可能更适合,尽管速度要慢得多。(下面有关“正确使用”的更多信息。double
0.1 + 0.2
0.30000000000000004
首先,您必须从区域设置中确定所使用的千位和小数点分隔符是什么(请参阅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
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);
...但同样,请务必设置适合您正在做的事情的规模。例如,如果您的刻度仅为 ,则 with 将代替 。除法特别棘手,您可能需要大幅的比例,然后最终舍入回更正常的货币水平等级(通常为2,但有时您可能想要更多的地方)。2
(43 / 7) * 7
RoundingMode.HALF_UP
42.98
43
如果你真的,真的,真的想要一个,使用Double.parseDouble
:double
// where `currencyString` is the string containing the currency
currencyString = currencyString
.replace(thousandsString, "")
.replace(decimalString, ".")
.replaceAll("[^\\d.-]", "");
double thisWillHaveIssues = Double.parseDouble(currencyString);