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?
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?
Share edited Mar 7 at 15:16 Craig 2,5191 gold badge22 silver badges27 bronze badges asked Mar 7 at 14:46 StarWeaverStarWeaver 11 silver badge4 bronze badges 2- 3 Note that Trim only removes spaces at the start and end of strings. – Bouke Commented Mar 7 at 14:52
- Which characters do you want to allow? Note that calling a phone number a number is not correct: it's a string which has digits in it as well as the possibility of other characters. – Andrew Morton Commented Mar 8 at 18:27
3 Answers
Reset to default 3The 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.)
If you want to validate the content of the phone numbers, I think there are better choices than trying to use IsNumeric
which is an outdated way to check on whether a string can be converted to a number (even for that purpose, I think a modern style would use TryParse
in the destination type, since IsNumeric
does not distinguish between integers and floating point numbers).
You will need to think about what sorts of variations are acceptable; do you care where the spaces are, or if there are spaces at all? What about non-space, non-numeric characters that are legal in phone numbers? I believe +
is more or less universal for indicating a country code. In North America, parentheses and hyphens are common as part of phone number description.
One option might be to strip out non-number characters and keep them without errors, e.g.
Dim numericChars As Char() = {"0"c, "1"c, "2"c, "3"c, "4"c, "5"c, "6"c, "7"c, "8"c, "9"c}
Dim phoneNumber As String = "03 21 71 52 33"
Return New String(phoneNumber.Where(Function(c) numericChars.Contains(c)).ToArray())
Depending on how specific you want to be about required formats, you could consider using regular expression validation. A format of five pairs of digits separated by single spaces should be easy to represent as a regex.
First, don't use IsNumeric
because this is VB compatibility function for conversions from earlier VB code to vb code. If you work with - use straight coding.
For instances such yours, zip codes, phone numbers, other such situations, good to have a general check and you can use System.Linq
to help
' chars that are allowed in your intake
Dim acceptableChars() As Char = {"("c, ")"c, "-"c, " "c, "0"c, "1"c, "2"c, "3"c, "4"c, "5"c, "6"c, "7"c, "8"c, "9"c}
Dim validPhoneNumber as string = "(999) 999-22-33"
Dim invalidPhoneNumber as string = "(99A) 999-22-33"
Dim isValid as Boolean
' check for - does not have any chars that not in acceptableChars
isValid = NOT validPhoneNumber.ToCharArray().Except(acceptableChars).Any()
Console.WriteLine("Phone {0} is {1}", validPhoneNumber, IF(isValid, "valid", "not valid"))
isValid = NOT invalidPhoneNumber.ToCharArray().Except(acceptableChars).Any()
Console.WriteLine("Phone {0} is {1}", invalidPhoneNumber, IF(isValid, "valid", "not valid"))
Result
Phone (999) 999-22-33 is valid
Phone (99A) 999-22-33 is not valid
Note: you can make an extension method on a string
that will check your string for such values, such as in
Dim myVal as string = "some val"
dim isValid as boolean = myVal.IsValidPhoneNumber()
Where IsValidPhoneNumber
is an extension method that takes a value of myVal
and does checking