How to untangle phone numbers
factbranch.com
factbranch.com
But 2 or more countries can use the same country code. The area code will determine which country you call to.
In the North American numbering plan +1 all numbers must have a fixed length 3 + 3 + 4.
In many other numbering plans the length varies. Both area code length and subscriber number length can vary. So it gets pretty complicated to parse a number. Basically rules don't help, you need a database and you need to update it regularly. No idea whether an open, non-commercial data set exists.
When I call to Germany Android shows the name of pretty small places. I believe Android reports every number you call to Google. But the database is probably still local, I believe locations are also shown when you have no data connection.
I am not from the US, but I understood there you might also need extensions to be dialled after the number proper.
e.g. 0123 456 7890
and 01/02 prefixes are landlines, 07 are mobile phones, 08 free, and 09 premium rate lines.
Wikipedia [0] says that there are 8 digit local numbers, and 2/5 digit area codes, but I happen not to have lived in a place that uses them until mobile phones took over anyway.
[0] https://en.wikipedia.org/wiki/List_of_dialling_codes_in_the_...
E.123 is for printing and general purpose use (as in use in URLS: https://datatracker.ietf.org/doc/html/rfc2806#section-2.2).
While the E.164 is (primarily) for storage and processing.
This will work for most of the world, but not everywhere. There are countries out there that don't use 00 as the international call prefix (Wikipedia has a list: https://en.wikipedia.org/wiki/List_of_international_call_pre...).
Take Austrialia, for instance, where 0011 is the prefix to strip to turn an international number into a local number, but 0018 is what you use to route a call to Optus. Australia's country code is not 18!
All of this can be prevented on mobile phones by simply placing a + at the front, but landlines (and systems simulating landlines, such as VoIP) quickly become part of a hellish web of deviating telephony standards.
Like email, the format may look simple, but only if you pretend not to have to deal with any other country or culture in the future.
For instance Turin, Milan, Rome and Genoa landline prefixes are 011, 02, 06, and 010. Any landline in Italy start with a leading zero BUT you can't strip it.
Let's say a Rome landline 061234567 can't be called like +3961234567 it MUST BE +39061234567. On contrary in France where essentially all numbers (mobile included, witch in Italy start with 3, no leading zero) start with zero you MUST cut the leading zero when you call it with an international prefix.
That's why in some countries the leading 0 is written as (0) meaning "you might or might not need it depending from witch extension of witch country you originate the call".
Sorry if you got stuck maintaining it :-)
As an aside, my fake phone number for bullshit store loyalty programs is 420-911-6969. CVS seems to cull it reliably, but other places have accepted it. I'm amazed that no human I've given that to has asked if it's actually my phone number.
I have access to a bunch of big marketing lists and there are always at least some Phonewords in there. The only big lists without them are the ones collected by forms that only allowed digits in the phone field.
Also on a personal level I have a "joke" number of (404)myname that I put into contact forms that allow it. Developers I talk to seem to have an easy time remembering my # because of the joke.
> What language is PhoneSpell written in?
> PhoneSpell is a system of multiple parts, some in C++, some in Perl, some in C, some in shtml, and some in shell scripts.
Checks out.
Or other things, depending on the country. For example, in Japan, area codes 090, 080, and 070 indicate mobile numbers. 050 means it's an IP phone, irrespective of area (hikari denwa).
Also, from a cell phone you can use just use 5555-5555 but from a line phone you must add a 15, i.e. 15-5555-5555. So users type whatever combination of 11, 911, 15 or nothing they think is the best one.
you need a bit of country-code based metadata to convert back to strings, but the storage format is ultra compact and unambiguous.
Edited to add:
It does depend on what you are doing with the numbers. Focussing on the storage side is missing the point. It’s about the ambiguity. In general I’ve found that anything other than integers is a mistake.
For example, *555 is not a valid phone number. You can’t put it in a tel: URL and you can’t dial it or send a text to it. It will work only in limited situations. If you want to store an extension it should be a separate field.
Once you realise that phone numbers are functional, almost exactly like IP addresses, you realise that storing them as integers has benefits because that way you literally are unable to store useless data.
Once you get in the habit of using only e164 numbers, the phone number becomes usable in almost any context, and you can make functional assumptions about it.
As an aside, it’s much easier to create fast and small prefix indexes on integers, but that’s a different story…
> In Israel, certain advertising numbers start with a *.
> In New Zealand, non-urgent traffic incidents can be reported by calling *555 from a mobile phone.
"Surely we won't ever need it"
So that leaves you with just the 10 digits. Which can be easily stored in an integer, which can then be formatted reliably for humans according to the international numbering plan.
Like IP addresses, phone numbers are just numbers. You can fuck about all you like by adding funny letters and brackets and complicated parsers (just like you can add dots and colons to an IP address), OR you can just store them as normalised E164 numbers, which will work everywhere and for which there are clear formatting rules. Just like you can store an IP address as an IP address datatype in most databases.
Almost nobody wants to store the NZ time service or 911 or anything else in a large database. Nobody is dialling an extension number over the PSTN network - that's like trying to include the port number in an IP address and calling it ... an IP address. Such numbers should be stored somewhere else.
I discovered that the tel: URL supports local numbers with context. So the bigint scheme can't represent valid tel: URLs.
A generic contact identifier that you’re only going to show to other humans can of course be a string. People can put whatever they want in there. But it won’t be useful for automation or other kinds of processing.
If you’re going to actually use the number in any kind of automation, including tel: urls, it’s better as an integer because then you’re forced to process the incoming number properly before you put it in the database.
In terms of E164, You’re not ever going to store numbers like 911 in a database of phone numbers that you’ll plug into automations.
The whole point of E164 is to normalise the international numbering system. Why would you not use the international telecommunications standard for numbering, to store telephone numbers that are intended to be used to contact people?
It’s the same as storing an IP address as a string. Sure, you can do it, but why? The only possible outcome is that you will eventually store useless strings that aren’t actually valid.
Of course the tel: url scheme can support E164 numbers. I mean unless your app is limited to only a single geography, why would you even want it to be local only?
They're not integers, they're strings. Strings of digits it's true, but still strings.
For most phone numbers, you just need to round trip them. They will be presented in the same context. It is better to store ambiguous numbers as entered, along with context, and let human figure it out than mess up.
> For most phone numbers, you just need to round trip them
That would be a great entry in a book, "myths developers believe about phone numbers".