James
James

Reputation: 82096

Convert any currency string to double

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

Answers (4)

IAmJersh
IAmJersh

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

Hans Olsson
Hans Olsson

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

hogarth45
hogarth45

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

Chris Taylor
Chris Taylor

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

Related Questions