检测VB.Net中的数字文化,即小数点/千位分隔符的句点或逗号

时间:2011-07-01 16:08:30

标签: asp.net vb.net globalization number-formatting

在VB.Net中,有没有一种方法可以自动检测数字字符串表示的文化?我会解释一下情况:

我们的asp.net网站接收船只数据的xml数据Feed。大多数情况下,价格的数字格式使用简单的非格式化整数,例如“999000”。这对我们来说很容易处理。

有时会有数千个分隔符的逗号和小数点的句点。此外,这很好,因为我们的数据导入了解这一点。示例“999,000.00”。

我们开始从法国获得一些数据,其中一些价格已与期间和千位分隔符相反,因为这是在许多欧洲国家完成的。例如。 “999.000,00”。这就是我们的系统将其解释为九九十九磅,而不是预期的九十九万九千磅。

不幸的是,数据Feed包含各种格式的价格,每个格式都没有任何文化指标。有没有人知道任何内置的.net函数会根据句点和逗号的位置自动检测字符串编号的文化?

4 个答案:

答案 0 :(得分:2)

据我所知,没有内置方法可以从数字字符串中确定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%安全,但它应该仍然比您当前的代码更好(至少在您提供的示例数据上按预期工作)。

答案 1 :(得分:2)

我在vbforums上发现了a thread,建议如何通过文化获取小数分隔符。

我制作了一个使用oledb,excel对象,mysql等在不同文件之间进行转换的转换器。使用" decimalSeparator"是我转换为Excel和Access文件时使数字格式正常工作的解决方案。

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

cellValue = cellValue.Replace(".", decimalSeparator ).Replace(",", decimalSeparator )

答案 2 :(得分:0)

不知道字符串可以格式化的方式的具体细节......这适用于您给出的三个示例

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

答案 3 :(得分:0)

'如果O.S.该变量为True。区域设置使用点作为小数分隔符,在其他情况下使用false。

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

原帖: https://www.linkedin.com/groups/8141257/8141257-6347113651027079171