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?
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é).
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"));
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.
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);
}
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