将任何货币字符串转换为双精度数

46

我需要在SQL server中存储多个货币。我知道SQL不支持所有不同类型的货币(除非我把它存储为字符串,但我不想这样做)。

我的想法是将所有值从其货币格式转换为标准double并将其存储。然后根据区域信息重新格式化显示。但是,我尝试做类似于:

var cultureInfo = new System.Globalization.CultureInfo("en-US");
double plain = return Double.Parse("$20,000.00", cultureInfo);

这似乎从来都不起作用,总是会抛出一个FormatException异常。即使删除货币符号并仅基于数字尝试操作也是同样的情况。这只是一个例子,我希望支持几乎任何类型的货币。

是否有一种标准方法可以去除货币并将其值作为双精度数获取?


4
不要将货币存储为double类型;例如,无法准确存储0.01。使用Decimal格式进行存储。 - staticsan
@statiscan - 我在这个问题之后不久更新了数据库,使用了小数。 - James
3个回答

112

我认为这应该可以运行:

double.Parse(currencyValue, NumberStyles.AllowCurrencySymbol | NumberStyles.Currency);

在这里,您可以了解更多关于NumberStyles的信息。

编辑:如果有人看到此答案而没有看其他答案/评论,请注意,此答案按照所写的回答了问题,但将货币存储为double并不是一个好主意,最好使用decimal代替。


7
是的,或者针对特定文化使用 double.Parse(currencyValue, NumberStyles.Currency, cultureInfo) - Noldorin
2
不是一个理想的解决方案,如果当前区域设置为en-US,则井号(例如)将无法被解析。 - illegal-immigrant
@James,还有一件事,NumberStyles.Any 包括货币。 - illegal-immigrant
3
我在Universal App中使用这段代码: double money; if (double.TryParse(currencyValue, NumberStyles.Currency, System.Globalization.CultureInfo.CurrentCulture, out money)) { } 注意:本翻译针对程序员,可能不易于普通人理解。 - Petr Voborník
我同意Hans的观点——货币应该以Decimal形式存储,这比double类型更精确——28位数字与15位数字相比。事实上,在货币方面,数字永远不会超过几万亿(除非存在严重通货膨胀!),但在进行这些金额的计算时,你仍然需要精确到分。 - Daniel Williams
2
我不认为这回答了问题。double.Parse(或者decimal.Parse)如何解析包含任何货币符号的字符串?这可能是 $ 或其他任何符号。目前,您只是解析当前文化中的货币符号。但即使您传递另一个符号,您也只会允许该符号。如何允许任何可能的文化/货币?这就是我理解这个问题的方式。 - Tim Schmelter

23

您应该将 NumberStyles 参数传递给 Parse 函数

Decimal.Parse("$20,000.00", NumberStyles.AllowCurrencySymbol | NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands, new CultureInfo("en-US"));
一些其他的建议,对于货币方面,我建议你使用Decimal。可能有点偏离主题,但更好的方法是将货币数据存储为DB中的Money,并添加货币代码以标识该值的货币。
是的,而且建议使用NumberStyles.Currency。这是一个预先计算的值,如果您仍然想使用字符串,则会更好。

1
我目前在使用float作为数据库类型,这不是一个好主意吗? - James
@Chris:原因是该列包含其他信息,即存储的不是所有内容都是货币,使用这种类型存储非货币值是否仍然安全? - James
@James,通常我认为在一个字段中存储不同类型的数据并不好,但是我不知道你的设计,你可能有非常好的理由。因此,我提供以下建议:我猜你有一个指示器来指示字段中的数据类型?我建议你使用一致的不变文化字符串格式存储数字值,并使用指示器来决定如何呈现数据。这样,当你需要呈现数据时,你可以始终提取数据并一致地转换为数字/小数,然后再做出呈现决策。 - Chris Taylor
可能我没有恰当地解释我的评论。存储在该列中的所有数据类型都是数字值,但有些只是普通整数,而有些可能是货币。我越想越觉得将整数存储为小数应该没问题,因为我可以将数字四舍五入。 - James
当我尝试解析£20.00时,出现了“输入字符串的格式不正确”的错误。我将CultureInfo更改为en-GB。 - RyanN1220

1

你也可以使用tryparse()函数

string input = "$2,000.00";
double parsed = 0d;
double.TryParse(input, NumberStyles.AllowCurrencySymbol | NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands, CultureInfo.CurrentCulture, out parsed))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接