2010-04-06 9 views
30

Ich habe zwei Nvarchar Felder in einer Datenbank, um den DataType und DefaultValue zu speichern, und ich habe einen DataType Double und Wert als 65.89875 in englischem Format.Wie man Zeichenfolge mit richtigen culturinfo in Doppelt konvertiert

Jetzt möchte ich, dass der Benutzer den Wert gemäß dem ausgewählten Browser-Sprachformat sieht (65,89875 in Englisch sollte als 65,89875 in Deutsch angezeigt werden). Wenn der Benutzer jetzt vom deutschen Format zu 65,89875, 65,89875 Äquivalent in Englisch, und den anderen Benutzeransichten von einem englischen Browser bearbeitet, kommt es als 6589875.

Dies passiert, weil in der Datenbank als 65,89875 gespeichert wurde in der nvarchar-Spalte und wenn sie mit englischer Kultur konvertiert wird, wird sie 6589875, da sie , als Trennzeichen betrachtet, das ein Dezimaloperator für Deutsch ist.

Wie bekomme ich das für alle Browser funktioniert?

+0

Warum sind Sie st oring Zahlen als Text zu beginnen? Wenn Sie das Schema möglicherweise ändern können, würde ich Ihnen dringend empfehlen, dies zu tun. –

Antwort

1

Sie können den Wert, den Benutzer bereitstellt, in ein Double konvertieren und als nvarchar mit Hilfe von FormatProviders erneut speichern. CultureInfo ist ein typischer FormatProvider. Angenommen, Sie kennen die Kultur, die Sie betreiben,

wird ausreichen, um die notwendige Transformation, wie;

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); 
} 
+1

"de-de" ist der Name der deutschen in Deutschland locale. – Richard

+0

@Richard, ich habe es gesucht aber konnte nicht finden, danke. – tafa

54

Sie benötigen ein einziges Gebietsschema zu definieren, die Sie für die Daten in der Datenbank gespeichert verwenden, ist die invariante Kultur dort genau für diesen Zweck.

Wenn Sie anzeigen, konvertieren Sie in den nativen Typ und dann für die Kultur des Benutzers formatieren.

z. zur Anzeige:

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

zu speichern:

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); 

PS. Es ist fast selbstverständlich, dass die Verwendung einer Spalte mit einem Datentyp, der mit den Daten übereinstimmt, noch besser wäre (aber manchmal gilt auch Legacy).

0

Ich habe diese Funktion in meinem Toolbelt seit Jahren (alle Funktions- und Variablennamen sind chaotisch und mischen Spanisch und Englisch, sorry dafür).

Sie können , und . verwenden, um die Dezimalstellen zu trennen und versuchen, das Beste zu tun, wenn beide Symbole verwendet werden.

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 
1

Sie können Ihre UI Kultur, was Sie wollen ändern, aber Sie sollten die Anzahl Separator wie folgt ändern:

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

Damit die Saiten wandelt wie folgt aus: „12.49“ statt "von 12,49" oder "12/49"

1

ich habe etwas Hilfe von MSDN, aber das ist meine Antwort:

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")); 
Verwandte Themen