libphonenumber - форматирование телефонных номеров без знания кода страны - PullRequest
0 голосов
/ 26 сентября 2018

Я слышал много хорошего из того, что кажется потрясающей библиотекой, но я попал в деликатную ситуацию.

Это первый проект, в котором я когда-либо работал, где я должен хранить телефонные номерав базе данных.

Я немного прочитал о формате E.164 и намерен сохранить все номера телефонов, использующие этот формат, в моей базе данных.

проблема, с которой я сталкиваюсь, это источник данных.У меня нет контроля над источником данных.Все, что я знаю, это то, что я получаю несколько телефонных номеров, и их формат не соответствует.У некоторых есть международное расширение, у некоторых нет.У некоторых есть круглые скобки, дефисы, ведущие 0 и т. Д., У некоторых нет.

Как я могу извлечь телефонные номера из указанного источника, отформатировать их в E.164, чтобы я мог их безопасно хранить?

Я пытался использовать метод PhoneNumberUtil#parse() без указания кода страны, поскольку у меня нет доступа к этой информации.

Посмотрите на следующий пример:

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

Тип ошибки: INVALID_COUNTRY_CODE.Регион по умолчанию отсутствует или недействителен.

В моем примере это номер французского мобильного телефона.Два начальных 0 работают, если вы набираете номер из-за пределов Франции, я полагаю.

Но библиотека не может понять это, поскольку она теряет код страны. Означает ли это, что не существует способа понять, откуда поступает этот конкретный номер телефона?

Документация кажется ясной:

public PhoneNumber parse(CharSequence numberToParse, String defaultRegion)

@ param defaultRegion регион, от которого мы ожидаем, что число будет.Это используется только если * анализируемый номер записан не в международном формате.Код страны для номера *
в этом случае будет сохранен как код региона по умолчанию.Если номер * гарантированно начинается с символа «+», за которым следует код вызова страны, то можно указать RegionCode.ZZ * или ноль.

Итак, если добавить +33

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

Тогда, естественно, результат будет:

Номер -> Код страны: 33 Национальный номер: 336555233634

Что я должен / могу делать, есликонечный пользователь предоставляет моему приложению номера телефонов, которые не начинаются с +?Я не могу поверить, что я один такой в ​​этой ситуации.

Спасибо за помощь!

Ответы [ 2 ]

0 голосов
/ 26 сентября 2018

Сохраните исходные телефонные номера в нерабочем столбце RAW_PHONE и канонический стандартизированный номер E.164 в столбце PHONE ("00" -> "+", "(" -> "" и т. Д.).Таким образом, вы подготовлены к проверочным спискам и ручным исправлениям, а также к улучшению конверсии.

Воображаемое имеет две телефонные колонки в таблице, а в качестве второго значения просто еще один добавочный номер -203.

Лучше не заполнять поле строгого режима, если преобразование не выполняется по коду страны или является сомнительным иным образом.По умолчанию это Франция, или что, когда пользователь живет в Бельгии?Можно утверждать, что источник (местоположение) регистрации пользователя определяет код страны по умолчанию.

0 голосов
/ 26 сентября 2018

Вам нужно использовать только формат E164.Здесь я взял Норвегию в качестве примера

У меня есть контрольный пример, который проверяет и дает номер телефона в одном формате.

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);
        }
    }

, и контрольный пример следующим образом.

// 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);
    }
}
...