Как преобразовать строку в удвоение с правильной cultureinfo - PullRequest
35 голосов
/ 06 апреля 2010

У меня есть два поля nvarchar в базе данных для хранения DataType и DefaultValue, и у меня есть DataType Double и значение как 65.89875 в английском формате.

Теперь я хочу, чтобы пользователь видел значение в соответствии с выбранным языковым форматом браузера (65,89875 на английском языке должно отображаться как 65,89875 на немецком языке). Теперь, если пользователь редактирует с немецкого формата на 65 89875, что эквивалентно 65 89875 на английском языке, и другие пользовательские просмотры из английского браузера, это будет 6589875.

Это происходит потому, что в базе данных он хранится как 65 89875 в столбце nvarchar, и при преобразовании с использованием английского языка он становится 6589875, поскольку он считает , разделителем, который является десятичным оператором для немецкого языка.

Как мне заставить это работать для всех браузеров?

Ответы [ 6 ]

60 голосов
/ 06 апреля 2010

Вам нужно определить одну локаль, которую вы будете использовать для данных, хранящихся в базе данных, именно для этой цели существует инвариантная культура.

Когда вы выводите на экран преобразование в собственный тип, а затем формат для пользовательской культуры.

например. для отображения:

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, userCulture, NumberStyles.Any, out value)) {
  // Error...
}
string forDB = value.ToString(CultureInfo.InvariantCulture);

PS. Почти само собой разумеется, что использование столбца с типом данных, который соответствует данным, было бы даже лучше (но иногда применяется устаревшее).

3 голосов
/ 21 июля 2017

Я получил помощь от 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"));
1 голос
/ 18 февраля 2019

Convert.ToDouble (x) также может иметь второй параметр, который указывает CultureInfo и когда вы устанавливаете его в System.Globalization.CultureInfo InvariantCulture результат всегда будет одинаковым.

1 голос
/ 15 июля 2017

Вы можете изменить свою культуру пользовательского интерфейса на что угодно, но вы должны изменить разделитель чисел следующим образом:

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»

1 голос
/ 06 апреля 2010

Вы можете преобразовать значение, предоставленное пользователем, в double и сохранить его снова как 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);
}
0 голосов
/ 06 апреля 2010

У меня есть эта функция в моем наборе инструментов много лет назад (все имена функций и переменных грязные и смешивают испанский и английский, извините за это).

Это позволяет пользователю использовать , и . для разделения десятичных дробей и будет стараться изо всех сил, если используются оба символа.

    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
...