Quelle est la meilleure façon de convertir les numéros de téléphone en format international (E. 164) en utilisant Java?

Quelle est la meilleure façon de convertir les numéros de téléphone en format international (E. 164) en utilisant Java?

A partir d'un "numéro de téléphone" et d'un numéro de pays (disons un code de pays ISO), je voudrais le convertir en un numéro de téléphone standard au format international E. 164.

je suis sûr que je peux le faire à la main assez facilement, mais je ne serais pas sûr que ça marcherait correctement dans toutes les situations.

quel cadre/bibliothèque/utilitaire Java recommanderiez-vous pour accomplir cette?

P.S. le "numéro de téléphone" pourrait être n'importe quoi identifiable par le grand public - comme

* (510) 786-0404
* 1-800-GOT-MILK
* +44-(0)800-7310658

ce dernier est mon préféré - il est la façon dont certaines personnes écrivent leur numéro au Royaume-Uni et signifie que vous devriez soit utiliser le +44 ou vous devriez utiliser le 0.

le numéro de format E. 164 doit être entièrement numérique et utiliser le code international complet du pays (par exemple+44)

24
demandé sur Vihung 2008-10-09 17:20:07

8 réponses

Google fournit une bibliothèque pour travailler avec les numéros de téléphone. Le même Qu'ils utilisent pour Android

http://code.google.com/p/libphonenumber/

String swissNumberStr = "044 668 18 00"
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
try {
  PhoneNumber swissNumberProto = phoneUtil.parse(swissNumberStr, "CH");
} catch (NumberParseException e) {
  System.err.println("NumberParseException was thrown: " + e.toString());
}

// Produces "+41 44 668 18 00"
System.out.println(phoneUtil.format(swissNumberProto, PhoneNumberFormat.INTERNATIONAL));
// Produces "044 668 18 00"
System.out.println(phoneUtil.format(swissNumberProto, PhoneNumberFormat.NATIONAL));
// Produces "+41446681800"
System.out.println(phoneUtil.format(swissNumberProto, PhoneNumberFormat.E164));
45
répondu Collin Peters 2011-03-10 19:30:00

parlant d'expérience à écrire ce genre de chose, il est vraiment difficile de faire avec 100% de fiabilité. J'ai écrit un code Java pour faire cela qui est raisonnablement bon au traitement des données que nous avons mais ne sera pas applicable dans chaque pays. Les Questions que vous devez poser sont:

est-ce que les correspondances entre les pays sont cohérentes? Les États-Unis utilisent beaucoup de ce lait (par exemple 1800-GOT-MILK), mais en Australie, à titre d'exemple, c'est assez rare. Ce que vous devez faire est de s'assurer que vous faisiez la configuration correcte pour le pays en question si elle varie (il ne pourrait pas). Je ne sais pas ce que les pays qui utilisent des alphabets différents (par exemple Cyrilic en Russie et dans les anciens pays de l'est) n';

Vous devez accepter que votre solution ne sera pas à 100% et vous ne devriez pas attendre d'elle. Vous devez prendre une "meilleure estimation" approche. Par exemple, il n'y a pas de vrai moyen de savoir que le 132345 est un numéro de téléphone valide en Australie, comme le 1300 123 456 mais que ce sont les deux seuls modèles qui sont pour les numéros 13xx et ils ne sont pas appelables de l'étranger;

vous devez aussi demander si vous voulez valider les régions (codes de zone). Je crois que les États-Unis utilisent un système où le deuxième chiffre du code régional est un 1 ou un 0. Cela peut avoir été le cas, mais je ne sais pas si ça s'applique toujours. Quoi qu'il en soit, de nombreux autres pays auront d'autres règles. En Australie, Les indicatifs régionaux valides pour les lignes terrestres et les téléphones mobiles (cellulaires) sont deux chiffres (le premier est 0). 08, 03 et 04 sont tous valables. 01 ne l'est pas. Comment accueillez-vous? Voulez-vous?

les pays utilisent différentes conventions peu importe le nombre de chiffres qu'ils écrivent. Vous devez décider si vous voulez l'accepter autre chose que la "norme". Ce sont toutes les communes en Australie:

  • (02) 1234 5678
  • 02 1234 5678
  • 0411 123 123 (mais je n'ai jamais vu 04 1112 3456)
  • 131 123
  • 13 1123
  • 131 123
  • 1 300 123 123
  • 1300 123 123
  • 02-1234-5678
  • 1300-234-234
  • +44 78 1234 1234
  • +44 (0)78 1234 1234
  • +44-78-1234-1234
  • +44-(0)78-1234-1234
  • 0011 44 78 1234 1234 (0011 est le standard de code d'appel international)
  • (44) 078 1234 1234 (pas fréquent)

Et c'est juste en haut de ma tête. Pour un pays. En France, par exemple, il est courant d'écrire le numéro de téléphone en paires (12 34 56 78) et ils le prononcent aussi de cette façon: au lieu de:

de l'onu (un), deux (deux), trois (trois)...

ses

douze (douze), trente-quatre (trente quatre)...

voulez-vous tenir compte de ce niveau de différence culturelle? Je suppose que non, mais la question mérite d'être examinée juste au cas où vous faites vos règles aussi strict.

certaines personnes peuvent aussi ajouter des numéros de poste sur les numéros de téléphone, éventuellement avec "ext" ou une abréviation similaire. Voulez-vous répondre à cela?

Désolé, pas de code ici. Juste une liste de questions à vous poser et à prendre en considération. Comme d'autres l'ont dit, une série d'expressions régulières peut faire beaucoup de ce qui précède, mais finalement les champs de numéros de téléphone sont (pour la plupart) du texte libre à la fin de la journée.

10
répondu cletus 2008-10-10 09:02:51

C'était ma solution:

public static String FixPhoneNumber(Context ctx, String rawNumber)
{
    String      fixedNumber = "";

    // get current location iso code
    TelephonyManager    telMgr = (TelephonyManager) ctx.getSystemService(Context.TELEPHONY_SERVICE);
    String              curLocale = telMgr.getNetworkCountryIso().toUpperCase();

    PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
    Phonenumber.PhoneNumber     phoneNumberProto;

    // gets the international dialling code for our current location
    String              curDCode = String.format("%d", phoneUtil.getCountryCodeForRegion(curLocale));
    String              ourDCode = "";

    if(rawNumber.indexOf("+") == 0)
    {
        int     bIndex = rawNumber.indexOf("(");
        int     hIndex = rawNumber.indexOf("-");
        int     eIndex = rawNumber.indexOf(" ");

        if(bIndex != -1)
        {
            ourDCode = rawNumber.substring(1, bIndex);
        }
        else if(hIndex != -1) 
        {               
            ourDCode = rawNumber.substring(1, hIndex);
        }
        else if(eIndex != -1)
        {
            ourDCode = rawNumber.substring(1, eIndex);
        }
        else
        {
            ourDCode = curDCode;
        }           
    }
    else
    {
        ourDCode = curDCode;
    }

    try 
    {
      phoneNumberProto = phoneUtil.parse(rawNumber, curLocale);
    } 

    catch (NumberParseException e) 
    {
      return rawNumber;
    }

    if(curDCode.compareTo(ourDCode) == 0)
        fixedNumber = phoneUtil.format(phoneNumberProto, PhoneNumberFormat.NATIONAL);
    else
        fixedNumber = phoneUtil.format(phoneNumberProto, PhoneNumberFormat.INTERNATIONAL);

    return fixedNumber.replace(" ", "");
}

j'espère que cela aide quelqu'un avec le même problème.

Profitez et utilisez librement.

3
répondu arksoft 2012-01-11 21:30:41

Merci pour les réponses. Comme indiqué dans la question initiale, je suis beaucoup plus intéressé par le formatage du numéro dans le format standard que je suis en déterminant si c'est un numéro de téléphone valide (comme dans authentique).

j'ai un code fait à la main qui prend actuellement une chaîne de numéros de téléphone (telle qu'entrée par l'utilisateur) et un contexte de pays source et de pays cible (le pays d'où le numéro est composé, et le pays d'où le numéro est composé) - ceci est connu du système) et fait ensuite la conversion suivante en pas

  1. enlever tous les espaces du nombre

  2. traduire tous les caractères alphabétiques en chiffres - à l'aide d'une table de recherche de lettres à chiffres (p. ex. A-->2, B-->2, C-->2, D-->3), etc. pour le clavier (je n'étais pas au courant que certains claviers distribuer ces différemment)

  3. supprimer toute ponctuation - conserver un " + " précédent intact s'il existe (dans le cas où le nombre est déjà dans une sorte de format international).

  4. déterminez si le numéro a un préfixe international de composition pour le contexte du pays - par exemple si le contexte source est le Royaume - Uni, je verrais s'il commence par un '00' - et le remplacerais par un '+'. Je ne vérifie pas actuellement si les chiffres qui suivent le " 00 " sont suivis du code de composition international du pays cible. Je cherche le préfixe international de numérotation pour le pays source dans une table de recherche (par ex. GO-->'00', NOUS-->'011', etc.)

  5. déterminer si le numéro a un préfixe de composition locale pour le contexte du pays - par exemple si le contexte source est le Royaume - Uni, je regarderais pour voir si cela commence par un '0' - et le remplacer par un '+' suivi du code de composition international pour le pays cible. Je cherche le préfixe de composition locale pour le pays source dans une table de recherche (par exemple GB-->'0', US-->'1' etc.), et l'indicatif international pour le pays cible dans une autre recherche tableau (par exemple, 'GB'='44', US='1')

Cela semble fonctionner pour tout ce que j'ai jeté à elle jusqu'à présent - à l'exception de l' +44(0)1234-567-890 situation - je vais ajouter un cas à vérifier pour que l'on.

écrire n'a pas été difficile - et je peux ajouter des cas spéciaux pour chaque exception étrange que je rencontre. Mais je voudrais vraiment savoir si il existe une solution standard.

les compagnies de téléphone semblent traiter avec cette chose tous les jours. Je ne suis jamais incohérent résultats lors de la composition de numéros à l'aide du RTPC. Par exemple, aux États-Unis (où les téléphones mobiles ont les mêmes indicatifs régionaux que les lignes terrestres, je pourrais composer le +1-123-456-7890, ou 011-1-123-456-7890 (où 011 est le préfixe international de composition aux États-Unis et 1 est le code international de composition pour les États-Unis), 1-123-456-7890 (où 1 est le préfixe local de composition aux États-Unis) ou même 456-7890 (en supposant que j'étais dans l'indicatif régional 123 à l'époque) et obtenir les mêmes résultats à chaque fois. Je suppose qu'à l'intérieur de ces composés les nombres sont convertis dans le même format standard E. 164, et que la conversion est tout fait dans le logiciel.

1
répondu Vihung 2008-10-12 01:35:18

Pour être honnête, il semble que vous avez la plupart des bases déjà couvertes.

le format + 44(0)800 parfois (incorrectement) utilisé au Royaume-Uni est ennuyeux et n'est pas strictement valide selon E. 123, qui est la recommandation de L'UIT-T sur la façon dont les numéros doivent être affichés. Si vous n'avez pas de copie de E. 123, regardez.

pour ce que ça vaut, le réseau téléphonique lui-même n'utilise pas toujours E. 164. Souvent, il y a un drapeau dans la signalisation ISDN généré par le PBX (ou dans le réseau si vous êtes sur un téléphone à vapeur) qui indique au réseau si le numéro composé est local, national ou international.

1
répondu Alnitak 2008-10-30 16:23:37

C'est une tâche très difficile, car les numéros de téléphone sont écrits différemment presque dans chaque pays.

nous avions l'habitude de garder une liste de REGEXPs (nous avons pris en charge 19 formats) pour analyser 3 parties d'un nombre et puis converti ces 3 parties en "+{1} {2} {3}".

Trier regexps par plus spécifique d'abord et ensuite prendre le premier qui réussit à Parser.

0
répondu Vilmantas Baranauskas 2008-10-09 15:56:25

dans certains pays, vous pouvez valider le 112 comme numéro de téléphone valide, mais si vous lui donnez un code de pays, il ne sera plus valide. Dans d'autres pays, vous ne pouvez pas valider le 112, mais vous pouvez valider le 911 comme numéro de téléphone valide.

j'ai vu des téléphones qui mettaient Q sur la 7 et Z sur la 9. J'ai vu des téléphones qui mettaient Q et Z sur la touche 0, et d'autres qui mettaient Q et Z sur la touche 1.

un indicatif régional qui existait hier pourrait ne pas exister aujourd'hui, et inversement.

dans la moitié de L'Amérique du Nord (code de pays 1), La Règle du deuxième chiffre était 0 ou 1 pour les indicatifs régionaux, mais cette règle a disparu il y a 10 ans.

0
répondu Windows programmer 2008-10-10 05:35:54

Je ne suis pas au courant d'une bibliothèque ou d'un cadre standard disponible pour formater les numéros de téléphone en E. 164.

la solution utilisée pour notre produit, qui nécessite le formatage PBX fourni caller-id dans E. 164, est de déployer un fichier (table de base de données) contenant les informations de format E. 164 pour tous les pays applicables. Ceci a l'avantage que l'application peut être mise à jour (pour gérer tous les cas de coin étrange dans les différents réseaux PSTN) w/out nécessitant des modifications à la la production de la base de code.

le tableau contient une rangée pour chaque code de pays et des renseignements concernant la longueur des indicatifs régionaux et la longueur des abonnés. Il peut y avoir plusieurs entrées pour un pays, selon les variations possibles en fonction de l'indicatif régional et de la longueur du numéro de l'abonné.

utiliser le plan de composition (partielle) du RTPC De La Nouvelle-Zélande comme exemple de la table..

CC  AREA_CODE  AREA_CODE_LENGTH  SUBSCRIBER  SUBSCRIBER_LENGTH
64                            1              7
64         21                 2              7
64        275                 3              6

nous faisons quelque chose semblable à ce que vous avez décrit, c.-à-d. rayer le numéro de téléphone fourni de tout caractère non numérique et ensuite le format basé sur diverses règles concernant la longueur totale du plan de nombres, le code d'accès extérieur et les codes d'accès interurbains/internationaux.

0
répondu Henk 2008-10-12 04:23:14