Updated 2012-10-02 10:13:36 by RLE

Richard Suchenwirth 2004-10-25 - Convert Canadian postcodes (only the first three characters) to USPS ZIP+4 codes:
 proc ca2us {postcode} {
   set map {0 1 2 3 4 5 6 7 8 9 -
      A B C D E F G H I - J K L M N O P Q R - S T U V W X Y Z}
   set res 00101-
   foreach {a b c} [split [string toup $postcode] ""] break
   foreach i {a b c} {
        append res [format %02d [lsearch $map [set $i]]]
   }
   set res
 }

Example:
 % ca2us M3H
 00101-240318

The first letter maps to province as follows (condensed from [1]):
 A         NL    Newfoundland and Labrador
 B         NS    Nova Scotia
 C         PE    Prince Edward Island
 E         NB    New Brunswick
 G,H,J     QC    Quebec
 K,L,M,N,P ON    Ontario
 R         MB    Manitoba
 S         SK    Saskatchewan
 T         AB    Alberta
 V         BC    British Columbia
 X         NU/NT Nunavut (X0A..C)/Northwest Territory (X0E, X0G, X1A)
 Y         YT    Yukon Territory

This specification can be neatly translated into a Tcl function to determine the province from a Canadian postcode:
 proc ca'province postcode {
   switch -- [string index $postcode 0] {
       A {return NL}
       B {return NS}
       C {return PE}
       E {return NB}
       G - H - J {return QC}
       K - L - M - N - P {return ON}
       R {return MB}
       S {return SK}
       T {return AB}
       V {return BC}
       X {if [regexp {^X0[ABC]} $postcode] {return NU} else {return NT}}
       Y {return YT}
       default {error "$postcode cannot be matched to a province"}
   }
 }