What is the best way for converting phone numbers into international format (E.164) using Java?

What is the best way for converting phone numbers into international format (E.164) using Java?

Given a 'phone number' and a country id (let's say an ISO country code), I would like to convert it into a standard E.164 international format phone number.

I am sure I can do it by hand quite easily - but I would not be sure it would work correctly in all situations.

Which Java framework/library/utility would you recommend to accomplish this?

P.S. The 'phone number' could be anything identifiable by the general public - such as

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

that last one is my favourite - it is how some people write their number in the UK and means that you should either use the +44 or you should use the 0.

The E.164 format number should be all numeric, and use the full international country code (e.g.+44)

Asked by: Marcus970 | Posted: 23-01-2022

Answer 1

Google provides a library for working with phone numbers. The same one they use for Android


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

Answered by: Daryl313 | Posted: 24-02-2022

Answer 2

Speaking from experience at writing this kind of thing, it's really difficult to do with 100% reliability. I've written some Java code to do this that is reasonably good at processing the data we have but won't be applicable in every country. Questions you need to ask are:

Are the character to number mappings consistent between countries? The US uses a lot of this (eg 1800-GOT-MILK) but in Australia, as one example, its pretty rare. What you'd need to do is ensure that you were doing the correct mapping for the country in question if it varies (it might not). I don't know what countries that use different alphabets (eg Cyrilic in Russia and the former Eastern block countries) do;

You have to accept that your solution will not be 100% and you should not expect it to be. You need to take a "best guess" approach. For example, theres no real way of knowing that 132345 is a valid phone number in Australia, as is 1300 123 456 but that these are the only two patterns that are for 13xx numbers and they're not callable from overseas;

You also have to ask if you want to validate regions (area codes). I believe the US uses a system where the second digit of the area code is a 1 or a 0. This may have once been the case but I'm not sure if it still applies. Whatever the case, many other countries will have other rules. In Australia, the valid area codes for landlines and mobile (cell) phones are two digits (the first is 0). 08, 03 and 04 are all valid. 01 isn't. How do you cater for that? Do you want to?

Countries use different conventions no matter how many digits they're writing. You have to decide if you want to accept something other than the "norm". These are all common in Australia:

  • (02) 1234 5678
  • 02 1234 5678
  • 0411 123 123 (but I've never seen 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 is the standard international dialling code)
  • (44) 078 1234 1234 (not common)

And thats just off the top of my head. For one country. In France, for example, its common the write the phone number in number pairs (12 34 56 78) and they pronounce it that way too: instead of:

un (one), deux (two), trois (three), ...


douze (twelve), trente-quatre (thirty four), ...

Do you want to cater for that level of cultural difference? I would assume not but the question is worth considering just in case you make your rules too strict.

Also some people may append extension numbers on phone numbers, possibly with "ext" or similar abbreviation. Do you want to cater for that?

Sorry, no code here. Just a list of questions to ask yourself and issues to consider. As others have said, a series of regular expressions can do much of the above but ultimately phone number fields are (mostly) free form text at the end of the day.

Answered by: Michael141 | Posted: 24-02-2022

Answer 3

This was my 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);
            ourDCode = curDCode;
        ourDCode = curDCode;

      phoneNumberProto = phoneUtil.parse(rawNumber, curLocale);

    catch (NumberParseException e) 
      return rawNumber;

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

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

I hope this helps someone with the same problem.

Enjoy and use freely.

Answered by: Audrey316 | Posted: 24-02-2022

Answer 4

Thanks for the answers. As stated in the original question, I am much more interested in the formatting of the number into the standard format than I am in determining if it is a valid (as in genuine) phone number.

I have some hand crafted code currently that takes a phone number String (as entered by the user) and a source country context and target country context (the country from where the number is being dialed, and the country to where the number is being dialed - this is known to the system) and then does the following conversion in steps

  1. Strip all whitespace from the number

  2. Translate all alpha into digits - using a lookup table of letter to digit (e.g. A-->2, B-->2, C-->2, D-->3) etc. for the keypad (I was not aware that some keypads distribute these differently)

  3. Strip all punctuation - keeping a preceding '+' intact if it exists (in case the number is already in some sort of international format).

  4. Determine if the number has an international dialling prefix for the country context - e.g. if source context is the UK, I would see if it starts with a '00' - and replace it with a '+'. I do not currently check whether the digits following the '00' are followed by the international dialing code for the target country. I look up the international dialing prefix for the source country in a lookup table (e.g. GB-->'00', US-->'011' etc.)

  5. Determine if the number has a local dialing prefix for the country context - e.g. if the source context is the UK, I would look to see if it starts with a '0' - and replace it with a '+' followed by the international dialing code for the target country. I look up the local dialing prefix for the source country in a lookup table (e.g. GB-->'0', US-->'1' etc.), and the international dialing code for the target country in another lookup table (e.g.'GB'='44', US='1')

It seems to work for everything I have thrown at it so far - except for the +44(0)1234-567-890 situation - I will add a special case check for that one.

Writing it was not hard - and I can add special cases for each strange exception I come across. But I would really like to know if there is a standard solution.

The phone companies seem to deal with this thing every day. I never get inconsistent results when dialing numbers using the PSTN. For example, in the US (where mobile phones have the same area codes as landlines, I could dial +1-123-456-7890, or 011-1-123-456-7890 (where 011 is the international dialing prefix in the US and 1 is the international dialing code for the US), 1-123-456-7890 (where 1 is the local dialing prefix in the US) or even 456-7890 (assuming I was in the 123 area code at the time) and get the same results each time. I assume that internally these dialed numbers get converted to the same E.164 standard format, and that the conversion is all done in software.

Answered by: Cherry458 | Posted: 24-02-2022

Answer 5

To be honest, it sounds like you've got most of the bases covered already.

The +44(0)800 format sometimes (incorrectly) used in the UK is annoying and isn't strictly valid according to E.123, which is the ITU-T recommendation for how numbers should be displayed. If you haven't got a copy of E.123 it's worth a look.

For what it's worth, the telephone network itself doesn't always use E.164. Often there'll be a flag in the ISDN signalling generated by the PBX (or in the network if you're on a steam phone) which tells the network whether the number being dialled is local, national or international.

Answered by: Edgar825 | Posted: 24-02-2022

Answer 6

In some countries you can validate 112 as a valid phone number, but if you stick a country code in front of it it won't be valid any more. In other countries you can't validate 112 but you can validate 911 as a valid phone number.

I've seen some phones that put Q on the 7 key and Z on the 9 key. I've seen some phones that put Q and Z on the 0 key, and some that put Q and Z on the 1 key.

An area code that existed yesterday might not exist today, and vice-versa.

In half of North America (country code 1), the second digit rule used to be 0 or 1 for area codes, but that rule went away 10 years ago.

Answered by: Kelvin918 | Posted: 24-02-2022

Answer 7

I'm not aware of a standard library or framework available for formatting telephone numbers into E.164.

The solution used for our product, which requires formatting PBX provided caller-id into E.164, is to deploy a file (database table) containing the E.164 format information for all countries applicable. This has the advantage that the application can be updated (to handle all the strange corner cases in various PSTN networks) w/out requiring changes to the production code base.

The table contains a row for each country code and information regarding area code length and subscriber length. There may be multiple entries for a country depending on what variations are possible with area code and subscriber number lengths.

Using New Zealand PSTN (partial) dial plan as an example of the table..

64                            1              7
64         21                 2              7
64        275                 3              6

We do something similar to what you have described, i.e. strip the provided telephone number of any non-digit characters and then format based on various rules regarding overall number plan length, outside access code, and long distance/international access codes.

Answered by: Connie649 | Posted: 24-02-2022

Similar questions

java - How can I read international characters from console

How can I read international characters from console in java?

java - how to deal with international time?

i build a new website.but the host is in USA.i am not in USA. i need get the time on the website page to compare with one local Variable. But because of time difference,it has 8 hous difference。how to solve this problom? my code SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss"); java.util.Date currentTime = new java.util.Date(); String dateString = formatter.format(currentTime); ...

unicode - Convert International String to \u Codes in java

How can I convert an international (e.g. Russian) String to \u numbers (unicode numbers) e.g. \u041e\u041a for OK ?

Retrieving MS Access column with international name from Java (encoding)

I need to import data from some legacy Access databases. I ran the code with some database file, and everything went fine. Now, I tried it with another one and the same code doesn't work. It seems to be related to character encoding, although I didn't specify anything (and wouldn't know where to do that). Double age = resultSet.getDouble("âge"); works on first db file, gives an SQ...

excel - International characters with Java

I am building an app that takes information from java and builds an excel spreadsheet. Some of the information contains international characters. I am having an issue when Russian characters, for example, are rendered correctly in Java, but when I send those characters to Excel, they are not rendered properly. I initially thought the issue was an encoding problem, but I am now thinking that the problem is simply not hav...

swing - Java: JFileChooser getting international filenames

I am using JFileChooser and getting file names with Chinese characters in them. JFileChooser displays them properly, and I want to be able to capture these file names and display them back to the user. I have filename: 03 玩愛之徒.mp3 But I end up displaying: 03 ????.mp3 In my code I get... File f1 = fileChooser.getSelectedFile(); log("f1="+ f1.getName()); ...

java - I'm using gwt and I can't capture international characters using a keypress event listener

onkeypress doesn't seem to capture characters such as vowels with accents eg "á". My application has a listener for keypress events. I run it on development mode and I'm using chrome and firefox on a mac computer. Googling the problem didn't offer me any information. I thought I'd also mention it should have nothing to do with encoding the source files as UTF-8. It is a different problem. Any ideas to sol...

java - Convert international phone number into local one

I'm trying to use libphonenumber google library to convert a number from international to local. The international number represent is: "+97239658320" The local number (here in Israel is): "039658320" http://code.google.com/p/libphonenumber/ PhoneNumberUtil phoneUtil = PhoneNumberUtil.ge...

Coldfusion with Java IDN handling international domains

I'm rewriting one of our forms so that it can handle international domains, but before I start on that i thought i would test the capabilities of handling IDNs. My thoughts were, should someone enter a domain like: http://清华大学.cn i would store it as the punycode in my database. With this in mind I then found the Java IDN handler and wrote this bit of test code: <cfset strUrl = "http://清...

Java Loses International Characters in Stream

I am having trouble reading international characters in Java. The default character set being used is UTF-8 and my Eclipse workspace is also set to this. I am reading a title of a video from the Internet (Gangam Style in fact ;) ) which contains Korean characters, I am doing this as follows: BufferedReader stdIn = new BufferedReader(new InputStreamReader(shellCommand.getInputStream())); Stri...

Still can't find your answer? Check out these amazing Java communities for help...

Java Reddit Community | Java Help Reddit Community | Dev.to Java Community | Java Discord | Java Programmers (Facebook) | Java developers (Facebook)