Postal Code Systems Around the World
Postal codes are unique identifiers that help route mail and packages. Each country has its own system with different formats, lengths, and rules.
What Postal Codes Tell Us
A postal code is more than just a delivery identifier:
| Information | Use Case |
|---|---|
| Geographic region | Shipping zone calculation |
| City/State | Address verification |
| Latitude/Longitude | Distance calculations |
| Urban vs Rural | Delivery time estimates |
US ZIP Codes
The US uses 5-digit ZIP codes, optionally extended to ZIP+4:
110001 - Basic ZIP (New York, NY)210001-1234 - ZIP+4 (specific building/floor)
Structure:
- First digit: Region (0-9)
- First 3 digits: Sectional center facility
- Last 2 digits: Post office or delivery area
- +4 extension: Specific delivery point
Pattern: /^\d{5}(-\d{4})?$/
javascript1const US_ZIP = /^\d{5}(-\d{4})?$/;23US_ZIP.test('10001'); // true4US_ZIP.test('10001-1234'); // true5US_ZIP.test('1234'); // false (too short)6US_ZIP.test('ABCDE'); // false (letters)
Regional distribution:
| First Digit | Region |
|---|---|
| 0 | Northeast (CT, MA, ME, NH, NJ, NY, PR, RI, VT, VI) |
| 1 | Northeast (DE, NY, PA) |
| 2-3 | Southeast (DC, MD, NC, SC, VA, WV) |
| 4 | Midwest (IN, KY, MI, OH) |
| 5 | Midwest (IA, MN, MT, ND, SD, WI) |
| 6 | Midwest (IL, KS, MO, NE) |
| 7 | South (AR, LA, OK, TX) |
| 8 | West (AZ, CO, ID, NM, NV, UT, WY) |
| 9 | West (AK, AS, CA, GU, HI, MH, OR, WA) |
Canadian Postal Codes
Canada uses alternating letter-digit format:
1M5V 3A8 - Toronto, ON2V6B 2W2 - Vancouver, BC
Structure:
- First letter: Province/territory (18 letters used)
- First 3 characters (FSA): Forward Sortation Area
- Last 3 characters (LDU): Local Delivery Unit
Pattern: /^[A-Z]\d[A-Z]\s?\d[A-Z]\d$/i
Letters NOT used: D, F, I, O, Q, U (avoid confusion with numbers) W and Z: Only in certain positions
javascript1const CA_POSTAL = /^[ABCEGHJ-NPRSTVXY]\d[ABCEGHJ-NPRSTV-Z]\s?\d[ABCEGHJ-NPRSTV-Z]\d$/i;
First letter by province:
| Letter | Province |
|---|---|
| A | Newfoundland |
| B | Nova Scotia |
| C | Prince Edward Island |
| E | New Brunswick |
| G-H | Quebec |
| J-K | Quebec (Montreal area) |
| L-N | Ontario |
| P | Ontario (Northern) |
| R | Manitoba |
| S | Saskatchewan |
| T | Alberta |
| V | British Columbia |
| X | NWT/Nunavut |
| Y | Yukon |
UK Postcodes
UK postcodes are complex with variable length:
1SW1A 2AA - Westminster, London2M1 1AA - Manchester3B1 1AA - Birmingham
Structure:
- Outward code (before space): Area + district
- Inward code (after space): Sector + unit
Valid formats:
| Format | Example |
|---|---|
| AN NAA | M1 1AA |
| ANN NAA | M60 1NW |
| AAN NAA | CR2 6XH |
| AANN NAA | DN55 1PT |
| ANA NAA | W1A 1HQ |
| AANA NAA | EC1A 1BB |
Pattern: /^[A-Z]{1,2}\d[A-Z\d]?\s?\d[A-Z]{2}$/i
javascript1const UK_POSTCODE = /^([A-Z]{1,2}\d[A-Z\d]?)\s?(\d[A-Z]{2})$/i;23function normalizeUKPostcode(code) {4 // Remove spaces, then add space before last 3 chars5 return code.replace(/\s/g, '').replace(/(.{3})$/, ' $1').toUpperCase();6}78normalizeUKPostcode('sw1a2aa'); // "SW1A 2AA"9normalizeUKPostcode('M1 1AA'); // "M1 1AA"
German PLZ (Postleitzahl)
Germany uses simple 5-digit codes:
110117 - Berlin Mitte280331 - München
Structure:
- First 2 digits: Region
- All 5 digits: Specific delivery area
Pattern: /^\d{5}$/
Regional distribution:
| Range | Region |
|---|---|
| 01-04 | Saxony, Brandenburg |
| 10-14 | Berlin |
| 20-27 | Hamburg, Bremen |
| 30-31 | Hannover |
| 40-47 | Düsseldorf |
| 50-53 | Köln |
| 60-65 | Frankfurt |
| 70-76 | Stuttgart |
| 80-87 | München |
| 90-96 | Nürnberg |
French Code Postal
France uses 5-digit codes similar to Germany:
175001 - Paris 1st arrondissement269001 - Lyon
Structure:
- First 2 digits: Département (01-95, plus overseas)
- Last 3 digits: Distribution office
Pattern: /^\d{5}$/
Paris arrondissements: 75001-75020
Japanese Postal Codes
Japan uses 7-digit codes with optional hyphen:
1150-0041 - Shibuya, Tokyo2〒150-0041 - With postal mark
Structure:
- First 3 digits: Region/prefecture
- Last 4 digits: Local area
Pattern: /^\d{3}-?\d{4}$/
Validation Levels
There are two levels of postal code validation:
1. Format Validation (Regex)
Check if the code matches the expected pattern:
javascript1function validateFormat(code, country) {2 const patterns = {3 US: /^\d{5}(-\d{4})?$/,4 CA: /^[A-Z]\d[A-Z]\s?\d[A-Z]\d$/i,5 GB: /^[A-Z]{1,2}\d[A-Z\d]?\s?\d[A-Z]{2}$/i,6 DE: /^\d{5}$/,7 FR: /^\d{5}$/8 };910 return patterns[country]?.test(code) || false;11}
2. Existence Validation (Database/API)
Check if the code actually exists:
javascript1async function validateExists(code, country) {2 // Use GeoNames API to verify3 const response = await fetch(4 `http://api.geonames.org/postalCodeSearchJSON?postalcode=${code}&country=${country}&username=demo`5 );6 const data = await response.json();7 return data.postalCodes?.length > 0;8}
Why both?
99999passes US format validation but doesn't exist- Format validation is fast (no network)
- Existence validation confirms deliverability
GeoNames: Free Postal Code Database
GeoNames provides free access to postal code data:
- Coverage: 150+ countries
- Data: City, state, coordinates for each code
- API: Free tier with 2000 requests/hour
- Download: Bulk data files available
We'll use GeoNames in the workshop to validate postal codes exist.
What's Next
In the workshop, you'll build a postal code validator that:
- Validates format by country
- Queries GeoNames to verify existence
- Returns city/region information
- Handles rate limiting gracefully