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