Reputation: 82096
I need to store multiple currencies in SQL server. I understand that SQL won't support all different types of currencies (unless I store it as a string, but I don't want to do that).
My idea was to convert all the values from their currency format to a standard double and store that instead. Then just re-format based on the culture info when displaying. However, I have tried doing something like e.g.
var cultureInfo = new System.Globalization.CultureInfo("en-US");
double plain = return Double.Parse("$20,000.00", cultureInfo);
This doesn't ever seem to work it always throws a FormatException
. Even removing the currency symbol and just trying to do this based on the number alone does the same thing. This is just an example I want to support pretty much any type of currency.
Is there a standard way of stripping out currency and getting the value as a double?
Upvotes: 47
Views: 84922
Reputation: 789
You can use CultureInfo.GetCulture(CultureTypes.AllCultures)
to get an array of IFormatProvider
objects for each culture.
Additionally, NumberStyles.Currency
will allow all the required symbols in a given culture.
Here's a method to parse a currency-formatted string to a double, regardless of the current culture on the environment (allows entry of any culture's currency markers).
public double ParseCurrencyToDouble(string currencyValue)
{
foreach (CultureInfo info in CultureInfo.GetCultures(CultureTypes.AllCultures))
{//Looks at every culture in turn until one works.
if (double.TryParse(currencyValue, NumberStyles.Currency, info, out double result))
{//Found a matching culture!
return result;
}
}
//No match found, likely not a currency.
throw new FormatException(); //Your error handling here
}
Not as efficient as a case where you know the current culture, but you at least cover all bases as the question requires.
And here's a TryParse
style implementation:
public bool TryParseCurrencyToDouble(string currencyValue, out double value)
{
foreach (CultureInfo info in CultureInfo.GetCultures(CultureTypes.AllCultures))
{//Looks at every culture in turn until one works.
if (double.TryParse(currencyValue, NumberStyles.Currency, info, out value))
{//Found a matching culture!
return true;
}
}
//No match found, likely not a currency.
return false;
}
Upvotes: 0
Reputation: 55009
I think this should work:
double.Parse(currencyValue, NumberStyles.AllowCurrencySymbol | NumberStyles.Currency);
Here you can see more about the NumberStyles.
Edit: In case anyone sees this answer without looking at the other answers/comments, this answer answered the question as written, but storing currency as a double
is not a good idea, and it would be better to use decimal instead.
Upvotes: 113
Reputation: 3657
You can also use the tryparse()
string input = "$2,000.00";
double parsed = 0d;
double.TryParse(input, NumberStyles.AllowCurrencySymbol | NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands, CultureInfo.CurrentCulture, out parsed))
Upvotes: 2
Reputation: 53699
You should pass NumberStyles to the Parse function
Decimal.Parse("$20,000.00", NumberStyles.AllowCurrencySymbol | NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands, new CultureInfo("en-US"));
A few other things, for currencies I would suggest you use Decimal. And this might be way off, but it might be better to store the currency data as Money in the DB and add a currency code to identify the currency of the value.
Yes, and the answers suggestung NumberStyles.Currency that would be better. It is a pre-Or'd value, if you still think you want to use the strings.
Upvotes: 25