使用java将不同国家的货币转换为双倍

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23990805/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 09:35:18  来源:igfitidea点击:

Converting different countrys currency to double using java

javacurrency

提问by user2649233

I have once scenario where in i get the currencies as a String, for eg:

我曾经有一个场景,我将货币作为字符串获取,例如:

$199.00

199.00 美元

R$ 399,00

399,00 雷亚尔

£25.00

£25.00

90,83

90,83

AED 449.00

449.00 迪拉姆

How do i convert these currencies to double in java?

我如何在 Java 中将这些货币转换为双倍?

采纳答案by Boris the Spider

Never use doublefor representing exact amounts

永远不要double用于表示精确的数量

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

嗯,当然可以,但是你需要真正了解浮点运算

Use a NumberFormat. Whilst it does handle somecurrencies, it's usually easier just to strip all the currency symbols. The NumberFormatwill use Localeto work out the delimiters to use:

使用一个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.,]",""));
}

This takes a Stringof the amount and the Locale. It then creates a BigDecimalparsing NumberFormatinstance. It uses replaceAlland regex to strip all but digits, .and ,from the number then parses it.

这需要 aString的数量和Locale。然后它创建一个BigDecimal解析NumberFormat实例。它使用replaceAll和正则表达式去除除数字之外的所有内容,.然后,从数字中解析它。

A quick demo against your examples:

针对您的示例的快速演示:

public static void main(String[] args) throws ParseException {
    final String dollarsA = "9.00";
    final String real = "R$ 399,00";
    final String dollarsB = "£25.00";
    final String tailingEuro = "90,83 ";
    final String dollarsC = "9.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 have simply used USwhere the decimal is .and FRANCEwhere the decimal is ,but you could use the correct Localefor the currency if you wish.

我只是用US其中小数点是.FRANCE其中小数是,,但你可以使用正确的Locale,如果你希望使用的货币。

回答by SteveL

Use contains,replace and valueOf

使用 contains、replace 和 valueOf

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

回答by T.J. Crowder

As David Wallace said, you don't (or if you do, you do it verycarefully and only if deeply informed about the issues), because doubleis usually not appropriate for use with currency values. It has issues like 0.1 + 0.2ending up being 0.30000000000000004(and other such). BigDecimalused properlyis probably better suited, although dramatically slower. (More on "used properly" below.)

正如大卫华莱士所说,你不这样做(或者如果你这样做,你会非常小心地做,并且只有在深入了解问题的情况下),因为double通常不适合用于货币价值。它有诸如0.1 + 0.2最终成为0.30000000000000004(以及其他类似问题)之类的问题。正确使用可能更适合,尽管速度要慢得多。(更多关于“正确使用”如下。)BigDecimal

First, you have to determine what the thousands and decimal separators being used are, from the locale (see Boris's excellent answer for more on that) or by having that information provided along with the string. In some cultures, they're ,(thousands) and .(decimal), e.g. "1,000.24", but in other cultures it's the other way around (e.g., "1.000,24"). For all I know, there are other characters used in some places. (You can't guess this from the string, you have no idea whether "1,234"means one thousand two hundred and thirty-four or one point two three four.)

首先,您必须确定所使用的千位分隔符和小数分隔符是什么,从语言环境(有关更多信息,请参阅 Boris 的优秀回答)或通过将这些信息与字符串一起提供。在某些文化中,它们是,(千)和.(十进制),例如“1,000.24”,但在其他文化中则相反(例如,“1.000,24”)。据我所知,在某些地方还使用了其他字符。(你不能从字符串中猜出这个,你不知道是"1,234"一千二百三十四还是一点二三四。)

Once you know what they are, you want to remove the thousands separators, convert the decimal to .(specifically), and then remove all non-digit, non-minus, non-decimals from the string:

一旦你知道它们是什么,你想删除千位分隔符,将小数转换为.(特别地),然后从字符串中删除所有非数字、非减号、非小数:

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

Then construct your BigDecimal:

然后构建你的BigDecimal

BigDecimal currency = new BigDecimal(currencyString);

...and set the scale and rounding modeappropriate to your program. Also be sure to read the Javadoc carefully for the various operation methods. For instance, as Peter Lawrey pointed out in the comments, a naive use of BigDecimalwill give you runtime exceptions:

...并设置适合您的程序的比例和舍入模式。另外请务必仔细阅读Javadoc,了解各种操作方法。例如,正如 Peter Lawrey 在评论中指出的那样,天真地使用 ofBigDecimal会给你运行时异常:

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

You can deal with those by providing rounding information:

您可以通过提供舍入信息来处理这些问题:

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

...but again, be sure to set a scale appropriate to what you're doing. For instance, if your scale is only 2, then (43 / 7) * 7with RoundingMode.HALF_UPwill be 42.98instead of 43. Dividing is particularly tricky, you may need significant scale and then a final rounding back to the more normal currency-level scales (typically 2, but sometimes you may want more places to the right than that).

...但同样,一定要设置一个适合你正在做的事情的比例。例如,如果您的比例仅为2,则(43 / 7) * 7withRoundingMode.HALF_UP42.98代替43。划分特别棘手,您可能需要较大的比例,然后最后四舍五入到更正常的货币级别比例(通常为 2,但有时您可能需要更多的右侧位置)。



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

如果你真的,真的,真的想要一个double,使用Double.parseDouble

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

回答by Johannes Papo

A simpler way is to use DecimalFormal as in the following example:

更简单的方法是使用 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);