2010-04-06 13 views
30

Tengo dos campos nvarchar en una base de datos para almacenar el DataType y DefaultValue, y tengo un DataType Double y un valor de 65.89875 en formato inglés.Cómo convertir un string a double con un cultureinfo adecuado

Ahora quiero que el usuario vea el valor según el formato de idioma del navegador seleccionado (65.89875 en inglés debería mostrarse como 65.89875 en alemán). Ahora si el usuario edita desde el formato alemán hasta 65,89875 que es equivalente a 65,89875 en inglés, y las otras vistas de usuario desde un navegador inglés, viene como 6589875.

Esto sucede porque en la base de datos se almacenó como 65,89875 en la columna nvarchar y cuando se convierte utilizando cultura inglesa se convierte en 6589875 ya que considera , como un separador que es un operador decimal para el alemán.

¿Cómo funciona esto para todos los navegadores?

+0

¿Por qué te st oring números como texto para comenzar? Si puede cambiar el esquema, le sugiero encarecidamente que lo haga. –

Respuesta

1

Puede convertir el valor que el usuario proporciona en un doble y almacenarlo de nuevo como nvarchar, con la ayuda de FormatProviders. CultureInfo es un FormatProvider típico. Suponiendo que conoce la cultura se está operando,

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

será suficiente para hacer la transformación NECESARIO, similares;

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" es el nombre de la localidad alemana en Alemania. – Richard

+0

@Richard, lo busqué pero no pude encontrar, gracias. – tafa

54

Es necesario definir un único local que va a utilizar para los datos almacenados en la base de datos, la referencia cultural de todos está ahí precisamente para este propósito.

Cuando visualiza convertir al tipo nativo y luego formatear para la cultura del usuario.

E.g. para mostrar:

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

de la tienda:

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 casi innecesario decir que usar una columna con un tipo de datos que coincida con los datos sería incluso mejor (pero a veces se aplica el legado).

0

Tengo esta función en mi toolbelt desde hace años (todos los nombres de funciones y variables son complicados y mezclan español e inglés, lo siento).

Permite al usuario usar , y . para separar los decimales y tratará de hacer lo mejor si se usan ambos símbolos.

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

Puede cambiar su cultura interfaz de usuario para cualquier cosa que desee, pero debe cambiar el separador de número de la siguiente manera:

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

Con esto, sus cadenas se convierte así: "12.49" en lugar de " 12,49" o "12/49"

1

tomé algo de ayuda de MSDN, pero esta es mi respuesta:

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")); 
Cuestiones relacionadas