Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

libphonenumber - formatting phone numbers without knowing the country code

I have heard a lot of good from what appears to be an awesome library but I find myself in a delicate situation.

This is the first project I have ever worked where I am supposed to store phone numbers in a database.

I have read a bit about the E.164 format and I do intend to store all phone numbers using this format in my database.

The problem I am facing, is the data source. I have no control over the data source. All I known is that I am receiving a bunch of phone numbers and their format is not consistent. Some have the international extension, some don't. Some have parenthesis, hyphens, leading 0, etc. some don't.

How could I possibly extract the phone numbers from said source, format them into E.164 so that I can store them safely ?

I have tried using the PhoneNumberUtil#parse() method without providing the country code, since I don't have access to that information.

Have a look at the following example:

System.out.printLn("Number -> " + phoneNumberUtil.parse("00336555233634", null).toString())

Error type: INVALID_COUNTRY_CODE. Missing or invalid default region.

In my example, the number is that of french mobile phone. The two starting 0 works if you dial from outside France, I believe.

But the library cannot understand it as it is laking the country code. Does that mean there does not exist a way to understand where that particular phone number is coming from ?

The documentation seems clear about it :

public PhoneNumber parse(CharSequence numberToParse, String defaultRegion)

@param defaultRegion region that we are expecting the number to be from. This is only used if * the number being parsed is not written in international format. The country_code for the *
number in this case would be stored as that of the default region supplied. If the number * is guaranteed to start with a '+' followed by the country calling code, then RegionCode.ZZ * or null can be supplied.

So, if add the +33

System.out.printLn("Number -> " + phoneNumberUtil.parse("+336555233634", null).toString())

Then naturally the result is:

Number -> Country Code: 33 National Number: 336555233634

What should / can I do if the end-user supplies my app with phone numbers that do not start with + ? I cannot believe I am the only one if this situation.

Thanks for the help !

like image 324
Mackovich Avatar asked Sep 26 '18 14:09

Mackovich


People also ask

How do you format a phone number correctly?

To format phone numbers in the US, Canada, and other NANP (North American Numbering Plan) countries, enclose the area code in parentheses followed by a nonbreaking space, and then hyphenate the three-digit exchange code with the four-digit number.

How do I fill my mobile number in international format?

A phone number in full international format includes a plus sign (+) followed by the country code, city code, and local phone number.

How do you enter mobile number prefix and country code?

Mobile numbers which are not local need to be prefixed by a 0 while dialing, or by +91 (91 is the country code for India). A mobile number written as +91-AAAAA BBBBB is valid throughout India, and in other countries where the + is recognized as a prefix to the country code.


1 Answers

You need to use E164Format only. Here I took Norway as example

I have test case which tests and give the phone number in one format.

public static String getE164FormattedMobileNumber(String mobile, String locale)
            throws PhoneNumberFormatException {
        try {
            PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
            PhoneNumber phoneProto = phoneUtil.parse(mobile, locale);
            if (phoneUtil.isValidNumber(phoneProto)
                    && phoneUtil.isPossibleNumberForType(phoneProto, PhoneNumberType.MOBILE)) {
                return phoneUtil.format(phoneProto, PhoneNumberFormat.E164);
            }
            throw new PhoneNumberFormatException(
                    "Mobile number is invalid with the provided locale");
        } catch (NumberParseException e) {
            throw new PhoneNumberFormatException("Error in parsing mobile number", e);
        }
    }

and the test case as follows.

// this is the test mobile used
    private String expectedMobileNumber = "+4746205615";
private List<String> sucessMobileNumbers;

private List<String> failMobileNumbers;

public PhoneNumberE164FormatTest() {
    sucessMobileNumbers =
            Arrays.asList(
                    "46205615",
                    "004746205615",
                    "+4746205615",
                    "4746205615",
                    "46205615",
                    "+47 46205615",
                    "462 05 615");
    failMobileNumbers = Arrays.asList("abcdsds3434", "abcdsds343?#4", "21448410", "9946739087");
}

@Test
public void e164FormattedMobileNumbersSucessCase() throws PhoneNumberFormatException {

    for (String mobileNumber : sucessMobileNumbers) {
        Assert.assertEquals(
                expectedMobileNumber,
                (PhoneNumberUtils.getE164FormattedMobileNumber(mobileNumber, NO)));
    }
}

@Test(expected = PhoneNumberFormatException.class)
public void e164FormattedMobileNumbersFailCase() throws PhoneNumberFormatException {
    for (String mobileNumber : failMobileNumbers) {
        PhoneNumberUtils.getE164FormattedMobileNumber(mobileNumber, NO);
    }
}
like image 142
VinuBibin Avatar answered Oct 04 '22 14:10

VinuBibin