This is the problem I'm working with: given a phone number from anywhere in the world and some location information (state, province, possibly country name if I'm lucky, etc.), return the ISO country code for that number.
For the purposes of this question, I will not focus on the location information, as that provides an alternative solution to determining the country code which doesn't even need to use the phone number anymore (though, it would be useful for validation purposes)
When I first started working on the problem, I was hoping there was a deterministic way to figure this out because there was some sort of international standard out there. It became immediately apparent that one does not exist for phone numbers. There are standards within countries, between countries (NANP for example), but no unified international standard.
Playing around with libphonenumbers for a few days, it seems to be able to provide accurate validation of a phone number if I'm given a country code (eg: CA for Canada, GB for United Kingdom, etc).
The library provides two methods: isPossibleNumber
, and isValidNumberForRegion
. This is the code I'm using
boolean isValid;
PhoneNumber number;
PhoneNumberUtil util = PhoneNumberUtil.getInstance();
String numStr = "(123) 456-7890";
for (String r : util.getSupportedRegions())
{
try {
// check if it's a possible number
isValid = util.isPossibleNumber(numStr, r);
if (isValid)
{
number = util.parse(numStr, r);
// check if it's a valid number for the given region
isValid = util.isValidNumberForRegion(number, r);
if (isValid)
System.out.println(r + ": " + number.getCountryCode() + ", " + number.getNationalNumber());
}
} catch (NumberParseException e)
{
e.printStackTrace();
}
}
So for example, if I took an arbitrary phone number like +44 20 7930 4832
and ran it through the method, I would get the following output
GB: 44, 2079304832
Now, that's assuming I'm given the dialing code (sometimes it's there). If I weren't given the dialing code, I might just get something like 20 7930 4832
, and the results are not as pretty
DE: 49, 2079304832
US: 1, 2079304832
GB: 44, 2079304832
FI: 358, 2079304832
AX: 358, 2079304832
RS: 381, 2079304832
CN: 86, 2079304832
NZ: 64, 2079304832
IN: 91, 2079304832
IR: 98, 2079304832
JP: 81, 2079304832
Given a phone number, I can run it through all of the different rules for every country and filter the list down from 244 to around 20 or less if I'm lucky, but I'm not sure if there's anything else I could do to try and guess the country.
### ### ####
(used in North America), and other places the pattern may be## #### ####
(from your example, this pattern appears to be British). That would help you guess but it would only be "probably" - and if the inputs have had all their whitespace and other characters removed, that probably won't work.##### #####
- the digits will still call someone in my city if I dial them, but it doesn't look like a "normally" formatted North American number. If you provide this to users, you might want to provide a warning in cases where you use this method to guess the country code.