# validation.phone-e164 Turns a phone number as someone typed it into E.164, the "+" form every SMS gateway and telephony API wants, reading national numbers as dialled from a default country. ## Scope: this is not libphonenumber It knows twelve countries, and for each only what normalising needs: the calling code, the trunk prefix dialled inside the country, the international prefix dialled to leave it, the range of national number lengths, and which digits a national number may start with. It does not know which ranges are allocated, whether a number is mobile or fixed, or any country's area codes. A pass means "plausibly a number in that country", not "a line that rings". For full numbering-plan validation, use Google's libphonenumber. Countries: GB, IE, US, CA, FR, DE, ES, IT, NL, AU, NZ, IN. A number in international form with any other calling code is `unknown-country-code`. ## How a number is read 1. Spaces, hyphens, dots and brackets are ignored. A "+" is allowed only at the start. Anything else, including the letters of a vanity number and an extension ("ext 12"), is `bad-character`. 2. A number starting with the default country's international prefix is read as international: 00 in most of Europe and India, 011 in North America, 0011 in Australia. 3. In international form the calling code is matched (calling codes are prefix-free, so there is only ever one match). Otherwise the default country applies, and with no default country the answer is `no-country`. 4. The trunk prefix (0, or 1 in North America) is dropped once if present. That handles "07700 900123" and the UK habit of writing "+44 (0)20 ...". Spain and Italy have no trunk prefix, and in Italy the leading 0 of a landline is part of the number: "06 1234 5678" is +390612345678. 5. The national number's length and first digit are checked against the table. North American area codes cannot start with 0 or 1; that is the only area-code rule applied. The US and Canada share +1 and the same rules, so which of them a +1 number belongs to is not reported: the result carries the calling code, not a country. | reason | meaning (checked in this order) | |---|---| | `empty` | no digits and no "+", or not a string | | `bad-character` | a character other than digits, separators and a leading "+" | | `bad-format` | a "+" that is not at the start, or nothing after it | | `no-country` | a national number and no default country | | `unknown-country-code` | a calling code outside the table | | `bad-length` | the national number is too short or too long for the country | | `bad-prefix` | the national number starts with a digit the country never uses | An unsupported `defaultCountry` is a programming error and throws (`unsupported default country "XX"`); "" means international form only. ## Data `data/phone-countries.json`. The calling codes are ITU-T E.164 assignments; trunk and international prefixes are those each national regulator publishes. The lengths are deliberately wide plausibility bounds, not the exact lengths per range: GB 9-10 (a few areas still have 9-digit national numbers), IE 7-9, US/CA 10, FR 9, DE 5-13 (German numbers vary in length by area), ES 9, IT 6-11, NL 9, AU 9, NZ 8-10, IN 10. Numbering plans do change; a change is a new version of this data. ## Sources - ITU-T Recommendation E.164 and the ITU list of country calling codes ("List of ITU-T Recommendation E.164 assigned country codes"): https://www.itu.int/pub/T-SP-E.164D - ITU-T operational bulletin annex, national numbering plans (per country trunk and international prefixes): https://www.itu.int/oth/T0202 - Ofcom, drama numbers used in the vectors (07700 900xxx, 020 7946 0xxx): https://www.ofcom.org.uk/phones-and-broadband/phone-numbers/numbers-for-drama 2.0.0 renames the function from `phoneE164` to `validatePhoneE164` (`validate_phone_e164` in Python and Rust), so every validator that returns a result record is `validateX` and every one that returns a bool is `isX`. Nothing else changed; 1.0.0 stays published under the old name.