Определить культуру числа в VB.Net, т. Е. Точку или запятую для десятичного разделителя / разделителя тысяч - PullRequest
2 голосов
/ 01 июля 2011

Есть ли в VB.Net способ автоматического определения культуры строкового представления числа? Я объясню ситуацию:

Наш веб-сайт asp.net получает XML-данные для лодок. В большинстве случаев в числовом формате цен используется простое неформатированное целое число, например "999000". Это легко для нас обрабатывать.

Иногда существуют запятые для тысяч разделителей и точки для десятичной точки. Кроме того, это нормально, поскольку наш импорт данных это понимает. Пример "999 000,00".

Мы начинаем получать некоторые данные из Франции, где некоторые цены были введены с точками и разделителями тысяч, наоборот, как это делается во многих европейских странах. Например. "999.000,00". Именно здесь наша система будет интерпретировать это как девятьсот девяносто девять фунтов вместо девятисот девяноста девяти тысяч фунтов, которые были предназначены.

К сожалению, в фиде данных содержатся цены в разных форматах без какого-либо индикатора культуры на каждом из них. Кто-нибудь знает о каких-либо встроенных функциях .net, которые будут автоматически определять культуру номера строки в зависимости от того, где находятся точка и запятая?

Ответы [ 4 ]

2 голосов
/ 12 октября 2016

Я нашел нить на vbforums, предлагающую, как получить десятичный разделитель по культуре.

Я сделал конвертер, который конвертирует разные файлы, используя oledb, excel object, mysql и другие.Использование «decimalSeparator» было решением для правильной работы числового формата при преобразовании в файлы Excel и Access.

Dim decimalSeparator As String = Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator

cellValue = cellValue.Replace(".", decimalSeparator ).Replace(",", decimalSeparator )
2 голосов
/ 01 июля 2011

Насколько я знаю, нет встроенного способа определения CultureInfo из числовой строки.И я серьезно сомневаюсь, что это когда-либо случится, потому что не существует 100% безопасного способа сделать это.

Пока вы не найдете лучшего решения (например, некоторые изменения на стороне отправителя), я думаю, лучшееВы можете уменьшить вероятность ошибки в два этапа:

1) Очистка и стандартизация входных данных :

Dim input as String = " 99 9.000,00 "
' This way you can remove unwanted characters (anything that is not a digit, and the following symbols: ".", "-", ",")
Dim fixedInput as String = Regex.Replace(input, "[^\d-,\.]", "")
' fixedInput now is "999.000,00"

2) Угадайте себяформат :

Dim indexOfDot as Integer = fixedInput.IndexOf(".")
Dim indexOfComma as Integer = fixedInput.IndexOf(",")
Dim cultureTestOrder as List(Of CultureInfo) = new List(Of CultureInfo)
Dim parsingResult as Double?
Try
    If indexOfDot > 0 And indexOfComma > 0 Then
        ' There are both the dot and the comma..let's check their order
        If indexOfDot > indexOfComma Then
            ' The dot comes after the comma. It should be en-US like Culture
            parsingResult = Double.Parse(fixedInput, NumberStyles.Number, CultureInfo.GetCultureInfo("en-US"))
        Else
            ' The dot comes after the comma. It should be it-IT like Culture
            parsingResult = Double.Parse(fixedInput, NumberStyles.Number, CultureInfo.GetCultureInfo("it-IT"))
        End If
    Else If indexOfDot = fixedInput.Length-3 Then
        ' There is only the dot! And it is followed by exactly two digits..it should be en-US like Culture
        parsingResult = Double.Parse(fixedInput, NumberStyles.Number, CultureInfo.GetCultureInfo("en-US"))
    Else If indexOfComma = fixedInput.Length-3 Then
        ' There is only the comma! And it is followed by exactly two digits..it should be en-US like Culture
        parsingResult = Double.Parse(fixedInput, NumberStyles.Number, CultureInfo.GetCultureInfo("it-IT"))
    End If
Catch
End Try
If Not parsingResult.HasValue Then
    Try
        ' There is no dot or comma, or the parsing failed for some reason. Let's try a less specific parsing.
        parsingResult = Double.Parse(fixedInput, NumberStyles.Any, NumberFormatInfo.InvariantInfo)
    Catch
    End Try 
End If
If Not parsingResult.HasValue Then
    ' Conversion not possible, throw exception or do something else
Else
    ' Use parsingResult.Value
End If

Таким образом, вы не на 100% в безопасности, но он должен быть все же лучше, чем ваш текущий код (и, по крайней мере, работает так, как ожидается на примере данных, предоставленных вами).1015 *

0 голосов
/ 14 декабря 2017

'Эта переменная имеет значение True, если в региональных настройках ОС используется точка в качестве десятичного разделителя, в других случаях - значение false.

Dim bAmerican as boolean=Cdec("0,2") > 1

Исходное сообщение: https://www.linkedin.com/groups/8141257/8141257-6347113651027079171

0 голосов
/ 01 июля 2011

Не зная специфики того, как по-разному можно форматировать строку ... Это работает для трех приведенных вами примеров

Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    Dim v As String = "999.123,45"
    Debug.WriteLine(foo(v))

    v = "999,123.45"
    Debug.WriteLine(foo(v))

    v = "999123"
    Debug.WriteLine(foo(v))
End Sub

Private Function foo(value As String) As Double
    Dim style As NumberStyles = NumberStyles.AllowThousands Or NumberStyles.AllowDecimalPoint
    Dim culture As CultureInfo = CultureInfo.InvariantCulture
    Dim rv As Double
    If Double.TryParse(value, style, culture, rv) Then
        Debug.WriteLine(",.Converted '{0}' to {1}.", value, rv)
    Else
        Dim styleES As NumberStyles = NumberStyles.AllowThousands Or NumberStyles.AllowDecimalPoint
        Dim cultureES As CultureInfo = CultureInfo.CreateSpecificCulture("es-ES")

        If Double.TryParse(value, styleES, cultureES, rv) Then
            Debug.WriteLine(".,Converted '{0}' to {1}.", value, rv)
        Else
            Throw New ArgumentException
        End If
    End If
    Return rv
End Function
...