Как преобразовать строку в double с правильной культуройinfo
У меня есть два поля nvarchar в базе данных для хранения DataType и DefaultValue, и у меня есть DataType Double и значение 65.89875 в английском формате.
Теперь я хочу, чтобы пользователь увидел значение в соответствии с выбранным форматом языка браузера (65.89875 на английском языке должно отображаться как 65 899875 на немецком языке). Теперь, если пользователь редактирует из немецкого формата 65,89875, что эквивалентно 65,89875 на английском языке, а другие пользователи просматривают английский браузер, он составляет 6589875.
Это происходит потому, что в базе данных он хранился как 65,89875 в столбце nvarchar и при преобразовании с использованием английской культуры он становится 6589875, поскольку он считает ,
разделителем, который является десятичным оператором для немецкого языка.
Как это сделать для всех браузеров?
Ответы
Ответ 1
Вам нужно определить одну локаль, которую вы будете использовать для данных, хранящихся в базе данных, именно для этой цели и существует инвариантная культура.
При отображении выполните преобразование в собственный тип, а затем в формат для пользовательской культуры.
Например. для отображения:
string fromDb = "123.56";
string display = double.Parse(fromDb, CultureInfo.InvariantCulture).ToString(userCulture);
хранить:
string fromUser = "132,56";
double value;
// Probably want to use a more specific NumberStyles selection here.
if (!double.TryParse(fromUser, NumberStyles.Any, userCulture, out value)) {
// Error...
}
string forDB = value.ToString(CultureInfo.InvariantCulture);
PS. Почти само собой разумеется, что использование столбца с типом данных, который соответствует данным, было бы даже лучше (но иногда применяется устаревшее).
Ответ 2
Я получил некоторую помощь от MSDN, но это мой ответ:
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
Вы можете изменить свою культуру пользовательского интерфейса на все, что хотите, но вы должны изменить разделитель чисел следующим образом:
CultureInfo info = new CultureInfo("fa-IR");
info.NumberFormat.NumberDecimalSeparator = ".";
Thread.CurrentThread.CurrentCulture = info;
Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;
С этим ваши строки преобразуются следующим образом: "12.49" вместо "12,49" или "12/49"
Ответ 4
Вы можете преобразовать значение, которое пользователь предоставляет двойнику, и сохранить его снова как nvarchar, с помощью FormatProviders. CultureInfo является типичным форматом FormatProvider. Предполагая, что вы знаете культуру, с которой вы работаете,
System.Globalization.CultureInfo EnglishCulture = new System.Globalization.CultureInfo("en-EN");
System.Globalization.CultureInfo GermanCulture = new System.Globalization.CultureInfo("de-de");
достаточно сделать необходимое преобразование, например:
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);
}
Ответ 5
Convert.ToDouble(x) также может иметь второй параметр, который указывает CultureInfo и когда вы устанавливаете его в
System.Globalization.CultureInfo InvariantCulture
результат всегда будет одинаковым.
Ответ 6
Я использую эту функцию в своем наборе инструментов еще много лет назад (все имена функций и переменных беспорядочны и смешивают испанский и английский языки, извините за это).
Он позволяет использовать ,
и .
для разделения десятичных знаков и будет стараться делать все возможное, если используются оба символа.
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