vb.netisnumeric

IsNumeric() gives different result on other computer


I'm working on a Windows application in VB.Net where the user has to enter phone numbers, which are validated to contain only numbers, using the IsNumeric function.

One of the things that I check is: IsNumeric(txtTelephone.Text.Trim) with txtTelephone.Text = "03 21 71 52 33

On my machine the result is True, but on another machine it returns False.

From what I understand IsNumeric() should not return True in this case but it does.

Here is the full code :

Private Function verificationChamps() As String

    Dim phoneNumber As String = "03 21 71 52 33"

    Return IsNumeric(phoneNumber.Trim)

End Function

Can someone explain the reason behind this?


Solution

  • The function considers the current Thread.CurrentCulture settings to interpret numeric formats just as TryParse does. Some cultures use a white space as thousands separator, others don't. A string like "03 21 71 52 33" will not be considered to be a valid number if e.g. a comma is used as thousands separator.

    This explains the different behaviors on different PCs.

    If you want to allow spaces, remove all the spaces and test whether the number is a valid Long number by excluding style elements like thousands or decimal separators by specifying NumberStyles.None and an invariant culture to exclude surprises.

    Private Function IsValidPhoneNumber(phoneNumber As String) As Boolean
        Dim d As Long
    
        Return Long.TryParse(phoneNumber.Replace(" ", ""), NumberStyles.None, CultureInfo.InvariantCulture, d)
    End Function
    

    This test

    Console.WriteLine(IsValidPhoneNumber("03 21 71 52 33"))
    Console.WriteLine(IsValidPhoneNumber("0321715233"))
    Console.WriteLine(IsValidPhoneNumber("032171.5233"))
    Console.WriteLine(IsValidPhoneNumber("032171,5233"))
    Console.WriteLine(IsValidPhoneNumber("+0321715233"))
    Console.WriteLine(IsValidPhoneNumber("-0321715233"))
    

    prints

    True
    True
    False
    False
    False
    False
    

    It probably also makes sense to test for a minimum and maximum length, but I think that sanitizing the number would be a better way to solve the problem. It is more user friendly to make the phone number valid if possible, instead of throwing an error message at him.

    It would return the number in a specific format if the number of digits corresponds to your country's phone numbers, but allow foreign phone numbers.

    Something like this:

    Private Function TryFormatPhoneNumber(phoneNumber As String, <Out()> ByRef result As String) As Boolean
        Const MinLength = 8, MaxLength = 15, StandardLength = 10
        Static invalid = New Regex("[^ 0-9]") 'Everything not a digit or a space
    
        result = invalid.Replace(phoneNumber, "")
        Dim trimmed As String = result.Replace(" ", "")
        If trimmed.Length < MinLength OrElse trimmed.Length > MaxLength Then
            result = Nothing
            Return False
        End If
        If trimmed.Length = StandardLength Then
            result = Long.Parse(trimmed, CultureInfo.InvariantCulture).ToString("000 000 00 00")
        End If
        Return True
    End Function
    

    (Adjust the min and max lengths to your needs.)