2010-04-06 18 views
30

Ho due campi nvarchar in un database per memorizzare DataType e DefaultValue, e ho un DataType Double e valore come 65.89875 in formato inglese.Come convertire la stringa in doppia con corretta culturainfo

Ora desidero che l'utente visualizzi il valore in base al formato della lingua del browser selezionato (65,89875 in inglese deve essere visualizzato come 65,89875 in tedesco). Ora se l'utente modifica dal formato tedesco a 65.89875 equivalenti in inglese a 65.89875 e le visualizzazioni degli altri utenti da un browser inglese è 6589875.

Ciò accade perché nel database è stato memorizzato come 65,89875 nella colonna nvarchar e quando viene convertito utilizzando la cultura inglese diventa 6589875 poiché considera , come un separatore che è un operatore decimale per il tedesco.

Come ottengo questo funzionamento per tutti i browser?

+0

Perché sei st oring numeri come testo per iniziare? Se è possibile modificare lo schema, suggerisco caldamente di farlo. –

risposta

1

È possibile convertire il valore che l'utente fornisce in una doppia e memorizzarlo di nuovo come nvarchar, con l'aiuto di FormatProviders. CultureInfo è un tipico FormatProvider. Supponendo che tu conosca la cultura che stai operando,

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

sarà sufficiente per eseguire la trasformazione necessaria, come;

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" è il nome della lingua tedesca in Germania. – Richard

+0

@Richard, l'ho cercato ma non ho trovato, grazie. – tafa

54

È necessario definire una singola locale che verrà utilizzata per i dati memorizzati nel database, la cultura invariabile è lì esattamente per questo scopo.

Quando si visualizza la conversione nel tipo nativo e quindi il formato per la cultura dell'utente.

E.g. visualizzare:

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

per memorizzare:

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. È quasi inutile dire che l'utilizzo di una colonna con un tipo di dati che corrisponda ai dati sarebbe ancora migliore (ma a volte si applica legacy).

0

Ho questa funzione nella mia barra degli strumenti da anni (tutti i nomi di funzioni e variabili sono disordinati e mescolano spagnolo e inglese, mi dispiace per quello).

Consente all'utente di utilizzare , e . per separare i decimali e proverà a fare il meglio se vengono utilizzati entrambi i simboli.

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

È possibile modificare la lingua dell'interfaccia utente per tutto quello che vuoi, ma si dovrebbe modificare il separatore numero come questo:

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

Con questo, le corde converte in questo modo: "12.49" invece di " 12,49" o "12/49"

1

ho preso un po 'di aiuto da MSDN, ma questa è la mia risposta:

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")); 
Problemi correlati