web-dev-qa-db-fra.com

Comment convertir une chaîne en double avec cultureinfo approprié

J'ai deux champs nvarchar dans une base de données pour stocker le DataType et le DefaultValue, et j'ai un DataType Double et une valeur de 65.89875 au format anglais.

Maintenant, je veux que l'utilisateur voie la valeur selon le format de langue du navigateur sélectionné (65.89875 en anglais doit être affiché ainsi que 65.89875 en allemand). Maintenant, si l'utilisateur édite du format allemand à 65 89875, ce qui correspond à l'équivalent 65,89875 en anglais, et que l'autre utilisateur est visualisé à partir d'un navigateur en anglais, il s'agit de 6589875.

Cela est dû au fait que dans la base de données, il a été stocké sous la forme 65 898 755 dans la colonne nvarchar et, lorsqu’il a été converti à l’aide de la culture anglaise, il devient 6589875, car il considère , comme un séparateur qui est un opérateur décimal pour l’allemand.

Comment puis-je faire en sorte que cela fonctionne pour tous les navigateurs?

32
Vinay Pandey

Vous devez définir un environnement local que vous utiliserez pour les données stockées dans la base de données. La culture invariante existe exactement à cette fin.

Lorsque vous affichez converti en type natif, puis formatez-le pour la culture de l'utilisateur.

Par exemple. afficher:

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

ranger:

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. Cela va presque sans dire qu’utiliser une colonne avec un type de données qui correspond aux données serait encore mieux (mais parfois, l’héritage est appliqué).

57
Richard

J'ai pris de l'aide de MSDN, mais voici ma réponse:

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"));
3
user2738678

Convert.ToDouble (x) peut également avoir un deuxième paramètre qui indique CultureInfo et lorsque vous le définissez sur System.Globalization.CultureInfo InvariantCulture Le résultat sera toujours identique.

1
Bolle

Vous pouvez convertir la valeur fournie par l'utilisateur en double et la stocker à nouveau sous nvarchar, à l'aide de FormatProviders . CultureInfo est un fournisseur de format typique. En supposant que vous connaissiez la culture que vous exploitez,

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

suffira pour faire la transformation nécessaire, comme;

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
tafa

Vous pouvez modifier votre culture d'interface utilisateur à votre guise, mais vous devez modifier le séparateur de nombres comme suit:

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

Avec cela, vos chaînes sont converties comme ceci: "12.49" au lieu de "12,49" ou "12/49"

J'ai cette fonction dans mon toolbelt depuis des années (tous les noms de fonction et de variable sont compliqués et mélangent espagnol et anglais, désolé pour cela).

Il permet à l'utilisateur d'utiliser , et . pour séparer les décimales et essaie de faire de son mieux si les deux symboles sont utilisés.

    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
0
Eduardo Molteni