parse - string to decimal c#
Cómo convertir string a double con la información cultural apropiada (5)
Necesita definir una configuración regional única que usará para los datos almacenados en la base de datos, la cultura invariante está ahí exactamente para este propósito.
Cuando visualiza convertir al tipo nativo y luego formatea para la cultura del usuario.
Ej. Para mostrar:
string fromDb = "123.56";
string display = double.Parse(fromDb, CultureInfo.InvariantCulture).ToString(userCulture);
Almacenar:
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);
PD. 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).
Tengo dos campos nvarchar en una base de datos para almacenar DataType y DefaultValue, y tengo un DataType Double y un valor como 65.89875 en formato inglés.
Ahora quiero que el usuario vea el valor según el formato de idioma del navegador seleccionado (65.89875 en inglés debe mostrarse como 65.89875 en alemán). Ahora bien, 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 en inglés, se obtiene como 6589875.
Esto sucede porque en la base de datos se almacenó como 65,89875 en la columna nvarchar y cuando se convierte usando cultura inglesa se convierte en 6589875 ya que considera ,
como un separador que es un operador decimal para el alemán.
¿Cómo hago que esto funcione para todos los navegadores?
Puede cambiar su cultura de interfaz de usuario a cualquier cosa que desee, pero debe cambiar el separador de números de esta 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 convierten así: "12.49" en vez de "12.49" o "12/49"
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 conoces la cultura que estás 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 necesaria, como;
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);
}
Recibí 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"));
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