[c#] How to convert string to double with proper cultureinfo

I have two nvarchar fields in a database to store the DataType and DefaultValue, and I have a DataType Double and value as 65.89875 in English format.

Now I want the user to see the value as per the selected browser language format (65.89875 in English should be displayed as 65,89875 in German). Now if the user edits from German format to 65,89875 which is 65.89875 equivalent in English, and the other user views from an English browser it comes as 6589875.

This happens because in the database it was stored as 65,89875 in the nvarchar column and when converted using English culture it becomes 6589875 since it considers , as a separator which is a decimal operator for German.

How do I get this working for all the browsers?

This question is related to c# .net localization globalization

The answer is


You can change your UI culture to anything you want, but you should change the number separator like this:

CultureInfo info = new CultureInfo("fa-IR");
info.NumberFormat.NumberDecimalSeparator = ".";
Thread.CurrentThread.CurrentCulture = info;
Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;

With this, your strings converts like this: "12.49" instead of "12,49" or "12/49"


I have this function in my toolbelt since years ago (all the function and variable names are messy and mixing Spanish and English, sorry for that).

It lets the user use , and . to separate the decimals and will try to do the best if both symbols are used.

    Public Shared Function TryCDec(ByVal texto As String, Optional ByVal DefaultValue As Decimal = 0) As Decimal

        If String.IsNullOrEmpty(texto) Then
            Return DefaultValue
        End If

        Dim CurAsTexto As String = texto.Trim.Replace("$", "").Replace(" ", "")

        ''// You can probably use a more modern way to find out the
        ''// System current locale, this function was done long time ago
        Dim SepDecimal As String, SepMiles As String
        If CDbl("3,24") = 324 Then
            SepDecimal = "."
            SepMiles = ","
        Else
            SepDecimal = ","
            SepMiles = "."
        End If

        If InStr(CurAsTexto, SepDecimal) > 0 Then
            If InStr(CurAsTexto, SepMiles) > 0 Then
                ''//both symbols was used find out what was correct
                If InStr(CurAsTexto, SepDecimal) > InStr(CurAsTexto, SepMiles) Then
                    ''// The usage was correct, but get rid of thousand separator
                    CurAsTexto = Replace(CurAsTexto, SepMiles, "")
                Else
                    ''// The usage was incorrect, but get rid of decimal separator and then replace it
                    CurAsTexto = Replace(CurAsTexto, SepDecimal, "")
                    CurAsTexto = Replace(CurAsTexto, SepMiles, SepDecimal)
                End If
            End If
        Else
            CurAsTexto = Replace(CurAsTexto, SepMiles, SepDecimal)
        End If
        ''// At last we try to tryParse, just in case
        Dim retval As Decimal = DefaultValue
        Decimal.TryParse(CurAsTexto, retval)
        Return retval
    End Function

You need to define a single locale that you will use for the data stored in the database, the invariant culture is there for exactly this purpose.

When you display convert to the native type and then format for the user's culture.

E.g. to display:

string fromDb = "123.56";
string display = double.Parse(fromDb, CultureInfo.InvariantCulture).ToString(userCulture);

to store:

string fromUser = "132,56";
double value;
// Probably want to use a more specific NumberStyles selection here.
if (!double.TryParse(fromUser, NumberStyles.Any, userCulture, out value)) {
  // Error...
}
string forDB = value.ToString(CultureInfo.InvariantCulture);

PS. It, almost, goes without saying that using a column with a datatype that matches the data would be even better (but sometimes legacy applies).


Use InvariantCulture. The decimal separator is always "." eventually you can replace "," by "." When you display the result , use your local culture. But internally use always invariant culture

TryParse does not allway work as we would expect There are change request in .net in this area:

https://github.com/dotnet/runtime/issues/25868


Convert.ToDouble(x) can also have a second parameter that indicates the CultureInfo and when you set it to System.Globalization.CultureInfo InvariantCulture the result will allways be the same.


You can convert the value user provides to a double and store it again as nvarchar, with the aid of FormatProviders. CultureInfo is a typical FormatProvider. Assuming you know the culture you are operating,

System.Globalization.CultureInfo EnglishCulture = new System.Globalization.CultureInfo("en-EN");
System.Globalization.CultureInfo GermanCulture = new System.Globalization.CultureInfo("de-de");

will suffice to do the neccesary transformation, like;

double val;
if(double.TryParse("65,89875", System.Globalization.NumberStyles.Float, GermanCulture,  out val))
{
    string valInGermanFormat = val.ToString(GermanCulture);
    string valInEnglishFormat = val.ToString(EnglishCulture);
}

if(double.TryParse("65.89875", System.Globalization.NumberStyles.Float, EnglishCulture,  out val))
{
    string valInGermanFormat = val.ToString(GermanCulture);
    string valInEnglishFormat = val.ToString(EnglishCulture);
}

I took some help from MSDN, but this is my answer:

double number;
string localStringNumber;
string doubleNumericValueasString = "65.89875";
System.Globalization.NumberStyles style = System.Globalization.NumberStyles.AllowDecimalPoint;

if (double.TryParse(doubleNumericValueasString, style, System.Globalization.CultureInfo.InvariantCulture, out number))
    Console.WriteLine("Converted '{0}' to {1}.", doubleNumericValueasString, number);
else
    Console.WriteLine("Unable to convert '{0}'.", doubleNumericValueasString);
localStringNumber =number.ToString(System.Globalization.CultureInfo.CreateSpecificCulture("de-DE"));

Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to .net

You must add a reference to assembly 'netstandard, Version=2.0.0.0 How to use Bootstrap 4 in ASP.NET Core No authenticationScheme was specified, and there was no DefaultChallengeScheme found with default authentification and custom authorization .net Core 2.0 - Package was restored using .NetFramework 4.6.1 instead of target framework .netCore 2.0. The package may not be fully compatible Update .NET web service to use TLS 1.2 EF Core add-migration Build Failed What is the difference between .NET Core and .NET Standard Class Library project types? Visual Studio 2017 - Could not load file or assembly 'System.Runtime, Version=4.1.0.0' or one of its dependencies Nuget connection attempt failed "Unable to load the service index for source" Token based authentication in Web API without any user interface

Examples related to localization

What's NSLocalizedString equivalent in Swift? Best practice multi language website Best practice for localization and globalization of strings and labels How to change language of app when user selects language? Lint: How to ignore "<key> is not translated in <language>" errors? Using ResourceManager How do I set the default locale in the JVM? What is the list of supported languages/locales on Android? Android: how to get the current day of the week (Monday, etc...) in the user's language? Get the current language in device

Examples related to globalization

Best practice for localization and globalization of strings and labels how to set default culture info for entire c# application String format currency How do I set the default locale in the JVM? Currency format for display Get current language in CultureInfo How to convert string to double with proper cultureinfo Regular expression for validating names and surnames? How can I detect the encoding/codepage of a text file