Parse MultiCurrency Strings to Decimals...

  • Thread starter Thread starter Navid Azimi
  • Start date Start date
N

Navid Azimi

What's the best way to parse a currency string to a decimal given the
possibility of multiple currencies? That is, my numeric string can be
($12.00) or -£12.00; in either case I want -12.00 to be returned. I
understand that this may be slightly difficult given non-symbol
currency strings (F or Kr) but I figured that the CultureInfo should be
able to take care of it somehow.

The closest solution I came up with, short of iterating through the
string and picking up each number, is the following:

public static decimal StripCurrencySymbol(string number)
{
CultureInfo culture = new CultureInfo("en-GB");
decimal newNumber;
try
{
newNumber = Decimal.Parse(number, NumberStyles.Any, culture);
}
catch
{
throw new Exception("...");
}
return newNumber;
}

The problem is, of course, that since the culture is set to UK, any
string with $ generates an exception. If I set the culture to US, any
string with £ will generate an exception. This problem continues with
the Euro symbol as well.

Is there any way to parse the string given "ANY" culture? I hope this
isn't something simple that I am missing. Thanks.
 
Navid,

In this case, you can create an instance of the NumberFormatInfo class,
and set the CurrencySymbol to the symbol for the current currency. You can
also set the CurrencyNegativePattern and CurrencyPositivePattern properties
to indicate what the pattern should be.

Then, you pass this instance to the Parse method of Decimal, and it
should give you the result that you want.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


What's the best way to parse a currency string to a decimal given the
possibility of multiple currencies? That is, my numeric string can be
($12.00) or -£12.00; in either case I want -12.00 to be returned. I
understand that this may be slightly difficult given non-symbol
currency strings (F or Kr) but I figured that the CultureInfo should be
able to take care of it somehow.

The closest solution I came up with, short of iterating through the
string and picking up each number, is the following:

public static decimal StripCurrencySymbol(string number)
{
CultureInfo culture = new CultureInfo("en-GB");
decimal newNumber;
try
{
newNumber = Decimal.Parse(number, NumberStyles.Any, culture);
}
catch
{
throw new Exception("...");
}
return newNumber;
}

The problem is, of course, that since the culture is set to UK, any
string with $ generates an exception. If I set the culture to US, any
string with £ will generate an exception. This problem continues with
the Euro symbol as well.

Is there any way to parse the string given "ANY" culture? I hope this
isn't something simple that I am missing. Thanks.
 
Thanks for the prompt response Nicholas, but how will I know what the
CurrencySymbol for a given numeric string will be?

The assumption here is that I could get any string, may it be:

£12.00
-£43
(£5.99)
34.00
12.5
(0)
-$12
($56.34)

These are some sample strings which should be parsed correctly to a
decimal value. I would also like to include the Euro, F, Kr, etc as
well. The point is, I will be getting a currency value (with or without
a currency symbol) where I would like to extract only the sign and
value.
 
Navid,

Well, if you don't know what the currency symbol for any given string
is, then how do you expect .NET to know? What I mean is, there isn't any
obvious way to determine this. You have to aid the parse mechanism along.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


Thanks for the prompt response Nicholas, but how will I know what the
CurrencySymbol for a given numeric string will be?

The assumption here is that I could get any string, may it be:

£12.00
-£43
(£5.99)
34.00
12.5
(0)
-$12
($56.34)

These are some sample strings which should be parsed correctly to a
decimal value. I would also like to include the Euro, F, Kr, etc as
well. The point is, I will be getting a currency value (with or without
a currency symbol) where I would like to extract only the sign and
value.
 
Hi Nicholas,

Thanks for your response. Your point is very well taken regarding how I
would expect .NET to know... but I was hoping that I could somehow set
the culture to ALL. Meaning that, the .NET framework would parse the
numeric string regardless -- given any acceptable currency symbol.

If this is a poor assumption, it appears that my only choice is to
iterate through the characters of the string and only pull out the
numeric values. (With distinction to negative values, comma separated
thousands, etc). I came up with the following function:

public static decimal StripCurrencySymbol(string number)
{
string temp = null;
decimal newNumber = 0;
try
{
// if number is negative using parenthesis
if (number.IndexOf("(") == 0 || number.IndexOf(")") > 0)
{
number = number.Replace("(", "");
number = number.Replace(")", "");
number = "-" + number;
}

for (int i = 0; i < number.Length; i++)
{
int c = (int) number;
if( c > 47 && c < 58 || // 0 through 9
c == 46 || // .
c == 45 ) // -
{
temp += ((char) c).ToString();
}
}
newNumber = Decimal.Parse(temp);
}
catch
{
throw new ArgumentOutOfRangeException("...");
}
return newNumber;
}

What do you think?

[By the way, I did some digging and I realized you've been answering my
questions since circa 2002!]

Thanks,
-- Navid
 
Navid,
In addition to the other comments.

I would consider using a RegEx or String.IndexOfAny to find & parse out the
currency symbol. Then based on the currency symbol lookup the specific
CultureInfo or NumericInfo class for that currency, which I then pass to
Decimal.Parse.

I would consider storing the currency symbol/culture pairs in a custom
configuration section in my app.config/web.config.

--
Hope this helps
Jay [MVP - Outlook]
..NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net


What's the best way to parse a currency string to a decimal given the
possibility of multiple currencies? That is, my numeric string can be
($12.00) or -£12.00; in either case I want -12.00 to be returned. I
understand that this may be slightly difficult given non-symbol
currency strings (F or Kr) but I figured that the CultureInfo should be
able to take care of it somehow.

The closest solution I came up with, short of iterating through the
string and picking up each number, is the following:

public static decimal StripCurrencySymbol(string number)
{
CultureInfo culture = new CultureInfo("en-GB");
decimal newNumber;
try
{
newNumber = Decimal.Parse(number, NumberStyles.Any, culture);
}
catch
{
throw new Exception("...");
}
return newNumber;
}

The problem is, of course, that since the culture is set to UK, any
string with $ generates an exception. If I set the culture to US, any
string with £ will generate an exception. This problem continues with
the Euro symbol as well.

Is there any way to parse the string given "ANY" culture? I hope this
isn't something simple that I am missing. Thanks.
 
Back
Top