free web tracker

Serving Industries Worldwide

Innovative Ways - Satisfied Clientele

Managing culture issues in .NET programming, a challenge for programmer – Handling Number parsing

alt text
It is a challenging job for asp.net software companies and developers to deal with culture dependent number parsing say, string to decimal or string to double etc. If these cases are not handled properly, it breaks the system anytime. ASP.NET software companies should aim at writing culture-safe and managed code that safe guards your applications from culture related issues.

What is number parsing?

All numeric types have two static parsing methods, TryParse and Parse, those are used to convert the string representation of a number into a numeric type.

Difference between TryParse and Parse is that TryParse method returns false whereas, the Parse method throws and exception if operation fails.

string numberStringRep = "35.88";

double number = double.Parse(numberStringRep);

Formatting conventions of a particular culture is always used by the Parse operation. If culture is not specified by passing a CultureInfo or NumberFromatInfo object, the culture associated with the current thread is used.

NumberFormat.NumberDecimalSeparator property is used to find the decimal separator string used by a culture.

// Returns: "."

new CultureInfo("en").NumberFormat.NumberDecimalSeparator;

// Returns: ","

new CultureInfo("es").NumberFormat.NumberDecimalSeparator;

// Returns: "."

CultureInfo.InvariantCulture.NumberFormat.NumberDecimalSeparator;

// Returns: ""

CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;

Why is it difficult to manage?

If number parsing from string to double is used in any application with multiple culture, developers in asp.net software companies should be cautious about the usage and probable issues associated.

An example, Cultures like German, French, Canadian, Spanish, etc., uses ‘,’ comma as a decimal separator whereas en-us uses ‘.’ dot as a decimal separator.

These are the cases when it becomes difficult to parse numbers from one culture to other.

Solution is to specify one rule for application like work with ‘.’ decimal separator or developer choice. One should also know the culture of the string being parsed from or decimal separator of that culture. Using this information, developer can easily manage them.

Common mistakes by programmers

Issue arises in number parsing when Culture gets change run time.

Let us understand this by an example. There is a potential bug in follwoing code, can you spot it?

Thread.CurrentThread.CurrentCulture = new CultureInfo("es");

string numberStringRep = "35.888";

double number = double.Parse(numberStringRep);

One must have realized that the parse call throws a FormatException. This is due to the current culture is Spanish and it uses “,” as the decimal separator whereas the string being parsed uses the “.” Dot as a decimal separator.

There are two ways to solve this problem:

  • Set the current culture to one with the correct number format for all Parse() calls.

    This option is tempting and developer should be very careful with this method as the current culture is used in other areas as well than just the parse methods. It can break other code.

    An example of this is the ToString() method, which also uses the current culture to determine its output:

    Thread.CurrentThread.CurrentCulture = new CultureInfo("en");

    35.88.ToString(); // Returns "35.88"

    Thread.CurrentThread.CurrentCulture = new CultureInfo("es");

    35.88.ToString(); // Returns "35,88"

  • Use overload that can be used to specify the culture to use for each Parse() call individually

    This option is safer unless developer is pretty sure to change the culture for all methods.

    string numberStringRep = "35,88";

    double number = double.Parse(numberStringRep, new CultureInfo("es"));

     Use following code snippet to identify the culture of number.

    double ResultVal;

    if (double.TryParse("75,89855",NumberStyles.Float, new CultureInfo("de-de"), out ResultVal))

    {

    double number = double.Parse(ResultVal.ToString(),CultureInfo.InvariantCulture);

    } //Output: 75.89855

     If culture is not known to the developer and knows a specific decimal separator and still wants to convert decimal number, use following code snippet.

    // get a temporary culture (clone) to modify

    var resci = CultureInfo.InvariantCulture.Clone() as CultureInfo;

    resci.NumberFormat.NumberDecimalSeparator = ",";

    decimal number = decimal.Parse("1,2", resci);

    MessageBox.Show(number.ToString()); //Output: 1.2

    When developer passes a CultureInfo instance to parse method, an overload method is called that takes an IFormatprovider instance. The culture’s NumberFormat property is of type NumberFromatInfo which also implements IFormatProvider.

    This means that instead of supplying a culture, developer could also pass its NumberFormat property to the parse methods:

    string numberStringRep = "35.88";

    double number = double.Parse(numberStringRep, new CultureInfo("en").NumberFormat);