views:

286

answers:

3

Hi All,

I have two nvarchar fields in database to store the DataType and DefaultValue, 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 english browser it comes as 6589875.

This happens because in DB it was stored as 65,89875 in nvarchar column and when converted using english culture it becomes 6589875 since it considers , as seperator which is decimal operator for german.

Any Idea how I get this working for all the browsers?

A: 

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);
}
tafa
"de-de" is the name of the German in Germany locale.
Richard
@Richard, I have looked for it but could not find, thank you.
tafa
+3  A: 

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).ToSring(userCulture);

to store:

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

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 , o . 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
Eduardo Molteni