Using NumberStyles to parse numbers in C# .NET Part 3
March 18, 2015 1 Comment
In the previous post we looked at some more values in the NumberStyles enumeration. In this finishing post we’ll look at some more compact enumeration values and how you can pass in your own number format provider for customised and culture-independent solutions.
We’ve seen that you can combine the NumberStyles enumeration values like here:
string rawNumber = "$(14)"; int parsedNumber = int.Parse(rawNumber, NumberStyles.AllowParentheses | NumberStyles.AllowCurrencySymbol);
It can be cumbersome to keep adding these flags to make sure all currency formats are covered. NumberStyles includes some composite values including NumberStyles.Currency. The Currency value combines all styles except for AllowExponent. If you start typing “NumberStyles.” in Visual Studio and investigate any of the values whose name does NOT start with “allow” then IntelliSense will show you the list of flags included in the composite. So the above currency example can be simplified as follows:
string rawNumber = "kr(14)"; int parsedNumber = int.Parse(rawNumber, NumberStyles.Currency);
We cannot only parse “normal” numbers, i.e. numbers of the decimal system but hexadecimal numbers as well. Consider the following example:
string rawNumber = "A2DB"; int parsedNumber = int.Parse(rawNumber, NumberStyles.HexNumber);
parsedNumber will be 41691.
In the previous post and the one before that we saw examples of culture dependent number parsing, here’s a reminder:
string rawNumber = "$(14)"; int parsed = int.Parse(rawNumber, NumberStyles.AllowParentheses | NumberStyles.AllowCurrencySymbol);
The above code only passes if the thread is set the a culture where the currency is denoted with a $ sign. In my case it fails as my PC follows the Swedish culture where the currency is denoted by “kr”. What if I want to parse an American currency regardless of the current culture? One option is to actively set the culture as follows:
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US"); string rawNumberCurrency = "$(14)"; int parsedCurrency = int.Parse(rawNumberCurrency, NumberStyles.Currency);
However, there’s a neater solution where you can pass in an IFormatProvider. The CultureInfo class has a NumberFormat property of type NumberFormatInfo which implements a range of numeric format info such as the currency symbol, the thousands separator, the percentage format etc.:
CultureInfo americanCulture = new CultureInfo("en-US"); string rawNumberCurrency = "$(14)"; int parsedCurrency = int.Parse(rawNumberCurrency, NumberStyles.Currency, americanCulture.NumberFormat);
The above code passes on my PC as well.
The above technique can be used for custom number formats as well. Imagine that you found your own country called “The Software Republic” where the currency is denoted by ‘{}’ and the thousand delimiter is ‘;’, e.g. ” {}(13;000) “. Easy:
NumberFormatInfo softwareRepNumberFormat = new NumberFormatInfo() { CurrencyGroupSeparator = ";" , CurrencySymbol = "{}" }; string rawNumberCurrencyDev = " {}(13;000) "; int parsedCurrencyDev = int.Parse(rawNumberCurrencyDev, NumberStyles.Currency, softwareRepNumberFormat);
parsedCurrencyDev will be correctly assigned -13000.
View all posts related to Globalization here.
Reblogged this on Brian By Experience.