Tcl Source Code

Hex Artifact Content
Login

Artifact 3ae913e2b730c6bc9c674c0bc33a2b60d27f903fef6d56abfffbd48f3275dc39:


0000: 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  #---------------
0010: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0020: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0030: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0040: 2d 2d 2d 2d 2d 2d 2d 0a 23 0a 23 20 74 63 6c 5a  -------.#.# tclZ
0050: 49 43 2e 74 63 6c 20 2d 2d 0a 23 0a 23 09 54 61  IC.tcl --.#.#.Ta
0060: 6b 65 20 74 68 65 20 74 69 6d 65 20 7a 6f 6e 65  ke the time zone
0070: 20 64 61 74 61 20 73 6f 75 72 63 65 20 66 69 6c   data source fil
0080: 65 73 20 66 72 6f 6d 20 41 72 74 68 75 72 20 4f  es from Arthur O
0090: 6c 73 6f 6e 27 73 0a 23 09 72 65 70 6f 73 69 74  lson's.#.reposit
00a0: 6f 72 79 20 61 74 20 68 74 74 70 73 3a 2f 2f 77  ory at https://w
00b0: 77 77 2e 69 61 6e 61 2e 6f 72 67 2f 74 69 6d 65  ww.iana.org/time
00c0: 2d 7a 6f 6e 65 73 2c 20 61 6e 64 20 70 72 65 70  -zones, and prep
00d0: 61 72 65 20 74 69 6d 65 20 7a 6f 6e 65 0a 23 09  are time zone.#.
00e0: 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 66 69 6c 65  information file
00f0: 73 20 66 6f 72 20 54 63 6c 2e 0a 23 0a 23 20 55  s for Tcl..#.# U
0100: 73 61 67 65 3a 0a 23 09 74 63 6c 73 68 20 74 63  sage:.#.tclsh tc
0110: 6c 5a 49 43 2e 74 63 6c 20 69 6e 70 75 74 44 69  lZIC.tcl inputDi
0120: 72 20 6f 75 74 70 75 74 44 69 72 0a 23 0a 23 20  r outputDir.#.# 
0130: 50 61 72 61 6d 65 74 65 72 73 3a 0a 23 09 69 6e  Parameters:.#.in
0140: 70 75 74 44 69 72 20 2d 20 44 69 72 65 63 74 6f  putDir - Directo
0150: 72 79 20 28 65 2e 67 2e 2c 20 74 7a 64 61 74 61  ry (e.g., tzdata
0160: 32 30 32 32 61 29 20 77 68 65 72 65 20 4f 6c 73  2022a) where Ols
0170: 6f 6e 27 73 20 73 6f 75 72 63 65 0a 23 09 09 20  on's source.#.. 
0180: 20 20 66 69 6c 65 73 20 61 72 65 20 74 6f 20 62    files are to b
0190: 65 20 66 6f 75 6e 64 2e 0a 23 09 6f 75 74 70 75  e found..#.outpu
01a0: 74 44 69 72 20 2d 20 44 69 72 65 63 74 6f 72 79  tDir - Directory
01b0: 20 28 65 2e 67 2e 2c 20 2e 2e 2f 6c 69 62 72 61   (e.g., ../libra
01c0: 72 79 2f 74 7a 64 61 74 61 29 20 77 68 65 72 65  ry/tzdata) where
01d0: 0a 23 09 09 20 20 20 20 74 68 65 20 74 69 6d 65  .#..    the time
01e0: 20 7a 6f 6e 65 20 69 6e 66 6f 72 6d 61 74 69 6f   zone informatio
01f0: 6e 20 66 69 6c 65 73 20 61 72 65 20 74 6f 20 62  n files are to b
0200: 65 20 70 6c 61 63 65 64 2e 0a 23 0a 23 20 52 65  e placed..#.# Re
0210: 73 75 6c 74 73 3a 0a 23 09 4d 61 79 20 70 72 6f  sults:.#.May pro
0220: 64 75 63 65 20 65 72 72 6f 72 20 6d 65 73 73 61  duce error messa
0230: 67 65 73 20 6f 6e 20 74 68 65 20 73 74 61 6e 64  ges on the stand
0240: 61 72 64 20 65 72 72 6f 72 2e 20 20 41 6e 20 65  ard error.  An e
0250: 78 69 74 0a 23 09 63 6f 64 65 20 6f 66 20 7a 65  xit.#.code of ze
0260: 72 6f 20 64 65 6e 6f 74 65 73 20 73 75 63 63 65  ro denotes succe
0270: 73 73 3b 20 61 6e 79 20 6f 74 68 65 72 20 65 78  ss; any other ex
0280: 69 74 20 63 6f 64 65 20 69 73 20 66 61 69 6c 75  it code is failu
0290: 72 65 2e 0a 23 0a 23 20 54 68 69 73 20 70 72 6f  re..#.# This pro
02a0: 67 72 61 6d 20 70 61 72 73 65 73 20 74 68 65 20  gram parses the 
02b0: 74 69 6d 65 7a 6f 6e 65 20 64 61 74 61 20 69 6e  timezone data in
02c0: 20 61 20 6d 65 61 6e 73 20 61 6e 61 6c 6f 67 6f   a means analogo
02d0: 75 73 20 74 6f 20 74 68 65 0a 23 20 27 7a 69 63  us to the.# 'zic
02e0: 27 20 63 6f 6d 6d 61 6e 64 2c 20 61 6e 64 20 70  ' command, and p
02f0: 72 6f 64 75 63 65 73 20 54 63 6c 20 74 69 6d 65  roduces Tcl time
0300: 20 7a 6f 6e 65 20 69 6e 66 6f 72 6d 61 74 69 6f   zone informatio
0310: 6e 20 66 69 6c 65 73 20 73 75 69 74 61 62 6c 65  n files suitable
0320: 0a 23 20 66 6f 72 20 6c 6f 61 64 69 6e 67 20 69  .# for loading i
0330: 6e 74 6f 20 74 68 65 20 27 63 6c 6f 63 6b 27 20  nto the 'clock' 
0340: 6e 61 6d 65 73 70 61 63 65 2e 0a 23 0a 23 2d 2d  namespace..#.#--
0350: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0360: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0370: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0380: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0390: 2d 2d 2d 2d 0a 23 0a 23 20 43 6f 70 79 72 69 67  ----.#.# Copyrig
03a0: 68 74 20 c2 a9 20 32 30 30 34 20 4b 65 76 69 6e  ht © 2004 Kevin
03b0: 20 42 2e 20 4b 65 6e 6e 79 2e 09 20 41 6c 6c 20   B. Kenny.. All 
03c0: 72 69 67 68 74 73 20 72 65 73 65 72 76 65 64 2e  rights reserved.
03d0: 0a 23 20 53 65 65 20 74 68 65 20 66 69 6c 65 20  .# See the file 
03e0: 22 6c 69 63 65 6e 73 65 2e 74 65 72 6d 73 22 20  "license.terms" 
03f0: 66 6f 72 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20  for information 
0400: 6f 6e 20 75 73 61 67 65 20 61 6e 64 20 72 65 64  on usage and red
0410: 69 73 74 72 69 62 75 74 69 6f 6e 0a 23 20 6f 66  istribution.# of
0420: 20 74 68 69 73 20 66 69 6c 65 2c 20 61 6e 64 20   this file, and 
0430: 66 6f 72 20 61 20 44 49 53 43 4c 41 49 4d 45 52  for a DISCLAIMER
0440: 20 4f 46 20 41 4c 4c 20 57 41 52 52 41 4e 54 49   OF ALL WARRANTI
0450: 45 53 2e 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ES..#-----------
0460: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0470: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0480: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0490: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 0a 23 20 44  -----------..# D
04a0: 65 66 69 6e 65 20 74 68 65 20 6e 61 6d 65 73 20  efine the names 
04b0: 6f 66 20 74 68 65 20 4f 6c 73 6f 6e 20 66 69 6c  of the Olson fil
04c0: 65 73 20 74 68 61 74 20 77 65 20 6e 65 65 64 20  es that we need 
04d0: 74 6f 20 6c 6f 61 64 2e 0a 23 20 57 65 20 61 76  to load..# We av
04e0: 6f 69 64 20 74 68 65 20 73 6f 6c 61 72 20 74 69  oid the solar ti
04f0: 6d 65 20 66 69 6c 65 73 20 61 6e 64 20 74 68 65  me files and the
0500: 20 6c 65 61 70 20 73 65 63 6f 6e 64 73 2e 0a 0a   leap seconds...
0510: 73 65 74 20 6f 6c 73 6f 6e 46 69 6c 65 73 20 7b  set olsonFiles {
0520: 0a 20 20 20 20 61 66 72 69 63 61 20 61 6e 74 61  .    africa anta
0530: 72 63 74 69 63 61 20 61 73 69 61 20 61 75 73 74  rctica asia aust
0540: 72 61 6c 61 73 69 61 0a 20 20 20 20 62 61 63 6b  ralasia.    back
0550: 77 61 72 64 20 65 74 63 65 74 65 72 61 20 65 75  ward etcetera eu
0560: 72 6f 70 65 20 6e 6f 72 74 68 61 6d 65 72 69 63  rope northameric
0570: 61 0a 20 20 20 20 73 6f 75 74 68 61 6d 65 72 69  a.    southameri
0580: 63 61 0a 7d 0a 0a 23 20 44 65 66 69 6e 65 20 74  ca.}..# Define t
0590: 68 65 20 79 65 61 72 20 61 74 20 77 68 69 63 68  he year at which
05a0: 20 74 68 65 20 44 53 54 20 69 6e 66 6f 72 6d 61   the DST informa
05b0: 74 69 6f 6e 20 77 69 6c 6c 20 73 74 6f 70 2e 0a  tion will stop..
05c0: 0a 73 65 74 20 6d 61 78 79 65 61 72 20 32 31 30  .set maxyear 210
05d0: 30 0a 0a 23 20 44 65 74 65 72 6d 69 6e 65 20 68  0..# Determine h
05e0: 6f 77 20 62 69 67 20 61 20 77 69 64 65 20 69 6e  ow big a wide in
05f0: 74 65 67 65 72 20 69 73 2e 0a 0a 73 65 74 20 4d  teger is...set M
0600: 41 58 57 49 44 45 20 5b 65 78 70 72 20 7b 77 69  AXWIDE [expr {wi
0610: 64 65 28 31 29 7d 5d 0a 77 68 69 6c 65 20 31 20  de(1)}].while 1 
0620: 7b 0a 20 20 20 20 73 65 74 20 6e 65 78 74 20 5b  {.    set next [
0630: 65 78 70 72 20 7b 77 69 64 65 28 24 4d 41 58 57  expr {wide($MAXW
0640: 49 44 45 20 2b 20 24 4d 41 58 57 49 44 45 20 2b  IDE + $MAXWIDE +
0650: 20 31 29 7d 5d 0a 20 20 20 20 69 66 20 7b 24 6e   1)}].    if {$n
0660: 65 78 74 20 3c 20 30 7d 20 7b 0a 09 62 72 65 61  ext < 0} {..brea
0670: 6b 0a 20 20 20 20 7d 0a 20 20 20 20 73 65 74 20  k.    }.    set 
0680: 4d 41 58 57 49 44 45 20 24 6e 65 78 74 0a 7d 0a  MAXWIDE $next.}.
0690: 73 65 74 20 4d 49 4e 57 49 44 45 20 5b 65 78 70  set MINWIDE [exp
06a0: 72 20 7b 2d 24 4d 41 58 57 49 44 45 2d 31 7d 5d  r {-$MAXWIDE-1}]
06b0: 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ..#-------------
06c0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
06d0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
06e0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
06f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 0a 23 20 6c 6f  ---------.#.# lo
0700: 61 64 46 69 6c 65 73 20 2d 2d 0a 23 0a 23 09 4c  adFiles --.#.#.L
0710: 6f 61 64 73 20 74 68 65 20 74 69 6d 65 20 7a 6f  oads the time zo
0720: 6e 65 20 66 69 6c 65 73 20 66 6f 72 20 65 61 63  ne files for eac
0730: 68 20 63 6f 6e 74 69 6e 65 6e 74 20 69 6e 74 6f  h continent into
0740: 20 6d 65 6d 6f 72 79 0a 23 0a 23 20 50 61 72 61   memory.#.# Para
0750: 6d 65 74 65 72 73 3a 0a 23 09 64 69 72 20 2d 20  meters:.#.dir - 
0760: 44 69 72 65 63 74 6f 72 79 20 77 68 65 72 65 20  Directory where 
0770: 74 68 65 20 74 69 6d 65 20 7a 6f 6e 65 20 73 6f  the time zone so
0780: 75 72 63 65 20 66 69 6c 65 73 20 61 72 65 20 66  urce files are f
0790: 6f 75 6e 64 0a 23 0a 23 20 52 65 73 75 6c 74 73  ound.#.# Results
07a0: 3a 0a 23 09 4e 6f 6e 65 2e 0a 23 0a 23 20 53 69  :.#.None..#.# Si
07b0: 64 65 20 65 66 66 65 63 74 73 3a 0a 23 09 43 61  de effects:.#.Ca
07c0: 6c 6c 73 20 27 6c 6f 61 64 5a 49 43 27 20 66 6f  lls 'loadZIC' fo
07d0: 72 20 65 61 63 68 20 63 6f 6e 74 69 6e 65 6e 74  r each continent
07e0: 27 73 20 64 61 74 61 20 66 69 6c 65 20 69 6e 20  's data file in 
07f0: 74 75 72 6e 2e 0a 23 09 52 65 70 6f 72 74 73 20  turn..#.Reports 
0800: 70 72 6f 67 72 65 73 73 20 6f 6e 20 73 74 64 6f  progress on stdo
0810: 75 74 2e 0a 23 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d  ut..#.#---------
0820: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0830: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0840: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0850: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 0a 70  -------------..p
0860: 72 6f 63 20 6c 6f 61 64 46 69 6c 65 73 20 7b 64  roc loadFiles {d
0870: 69 72 7d 20 7b 0a 20 20 20 20 76 61 72 69 61 62  ir} {.    variab
0880: 6c 65 20 6f 6c 73 6f 6e 46 69 6c 65 73 0a 20 20  le olsonFiles.  
0890: 20 20 66 6f 72 65 61 63 68 20 66 69 6c 65 20 24    foreach file $
08a0: 6f 6c 73 6f 6e 46 69 6c 65 73 20 7b 0a 09 70 75  olsonFiles {..pu
08b0: 74 73 20 22 6c 6f 61 64 69 6e 67 3a 20 5b 66 69  ts "loading: [fi
08c0: 6c 65 20 6a 6f 69 6e 20 24 64 69 72 20 24 66 69  le join $dir $fi
08d0: 6c 65 5d 22 0a 09 6c 6f 61 64 5a 49 43 20 5b 66  le]"..loadZIC [f
08e0: 69 6c 65 20 6a 6f 69 6e 20 24 64 69 72 20 24 66  ile join $dir $f
08f0: 69 6c 65 5d 0a 20 20 20 20 7d 0a 20 20 20 20 72  ile].    }.    r
0900: 65 74 75 72 6e 0a 7d 0a 0a 23 2d 2d 2d 2d 2d 2d  eturn.}..#------
0910: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0920: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0930: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0940: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0950: 0a 23 0a 23 20 63 68 65 63 6b 46 6f 72 77 61 72  .#.# checkForwar
0960: 64 52 75 6c 65 52 65 66 73 20 2d 2d 0a 23 0a 23  dRuleRefs --.#.#
0970: 09 43 68 65 63 6b 73 20 74 6f 20 6d 61 6b 65 20  .Checks to make 
0980: 73 75 72 65 20 74 68 61 74 20 61 6c 6c 20 72 65  sure that all re
0990: 66 65 72 65 6e 63 65 73 20 74 6f 20 44 61 79 6c  ferences to Dayl
09a0: 69 67 68 74 20 53 61 76 69 6e 67 0a 23 09 54 69  ight Saving.#.Ti
09b0: 6d 65 20 72 75 6c 65 73 20 64 65 73 69 67 6e 61  me rules designa
09c0: 74 65 20 64 65 66 69 6e 65 64 20 72 75 6c 65 73  te defined rules
09d0: 2e 0a 23 0a 23 20 50 61 72 61 6d 65 74 65 72 73  ..#.# Parameters
09e0: 3a 0a 23 09 4e 6f 6e 65 2e 0a 23 0a 23 20 52 65  :.#.None..#.# Re
09f0: 73 75 6c 74 73 3a 0a 23 09 4e 6f 6e 65 2e 0a 23  sults:.#.None..#
0a00: 0a 23 20 53 69 64 65 20 65 66 66 65 63 74 73 3a  .# Side effects:
0a10: 0a 23 09 50 72 6f 64 75 63 65 73 20 61 6e 20 65  .#.Produces an e
0a20: 72 72 6f 72 20 6d 65 73 73 61 67 65 20 61 6e 64  rror message and
0a30: 20 69 6e 63 72 65 61 73 65 73 20 74 68 65 20 65   increases the e
0a40: 72 72 6f 72 20 63 6f 75 6e 74 20 69 66 0a 23 09  rror count if.#.
0a50: 61 6e 79 20 75 6e 64 65 66 69 6e 65 64 20 72 75  any undefined ru
0a60: 6c 65 73 20 61 72 65 20 70 72 65 73 65 6e 74 2e  les are present.
0a70: 0a 23 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  .#.#------------
0a80: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0a90: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0aa0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0ab0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 0a 70 72 6f 63  ----------..proc
0ac0: 20 63 68 65 63 6b 46 6f 72 77 61 72 64 52 75 6c   checkForwardRul
0ad0: 65 52 65 66 73 20 7b 7d 20 7b 0a 20 20 20 20 76  eRefs {} {.    v
0ae0: 61 72 69 61 62 6c 65 20 66 6f 72 77 61 72 64 52  ariable forwardR
0af0: 75 6c 65 52 65 66 73 0a 20 20 20 20 76 61 72 69  uleRefs.    vari
0b00: 61 62 6c 65 20 72 75 6c 65 73 0a 0a 20 20 20 20  able rules..    
0b10: 66 6f 72 65 61 63 68 20 7b 72 75 6c 65 20 77 68  foreach {rule wh
0b20: 65 72 65 7d 20 5b 61 72 72 61 79 20 67 65 74 20  ere} [array get 
0b30: 66 6f 72 77 61 72 64 52 75 6c 65 52 65 66 73 5d  forwardRuleRefs]
0b40: 20 7b 0a 09 69 66 20 7b 21 5b 69 6e 66 6f 20 65   {..if {![info e
0b50: 78 69 73 74 73 20 72 75 6c 65 73 28 24 72 75 6c  xists rules($rul
0b60: 65 29 5d 7d 20 7b 0a 09 20 20 20 20 66 6f 72 65  e)]} {..    fore
0b70: 61 63 68 20 7b 66 69 6c 65 4e 61 6d 65 20 6c 6e  ach {fileName ln
0b80: 6f 7d 20 24 77 68 65 72 65 20 7b 0a 09 09 70 75  o} $where {...pu
0b90: 74 73 20 73 74 64 65 72 72 20 22 24 66 69 6c 65  ts stderr "$file
0ba0: 4e 61 6d 65 3a 24 6c 6e 6f 3a 63 61 6e 27 74 20  Name:$lno:can't 
0bb0: 6c 6f 63 61 74 65 20 72 75 6c 65 20 5c 22 24 72  locate rule \"$r
0bc0: 75 6c 65 5c 22 22 0a 09 09 69 6e 63 72 20 65 72  ule\""...incr er
0bd0: 72 6f 72 43 6f 75 6e 74 0a 09 20 20 20 20 7d 0a  rorCount..    }.
0be0: 09 7d 0a 20 20 20 20 7d 0a 7d 0a 0a 23 2d 2d 2d  .}.    }.}..#---
0bf0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0c00: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0c10: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0c20: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0c30: 2d 2d 2d 0a 23 0a 23 20 6c 6f 61 64 5a 49 43 20  ---.#.# loadZIC 
0c40: 2d 2d 0a 23 0a 23 09 4c 6f 61 64 20 6f 6e 65 20  --.#.#.Load one 
0c50: 63 6f 6e 74 69 6e 65 6e 74 27 73 20 64 61 74 61  continent's data
0c60: 20 69 6e 74 6f 20 6d 65 6d 6f 72 79 2e 0a 23 0a   into memory..#.
0c70: 23 20 50 61 72 61 6d 65 74 65 72 73 3a 0a 23 09  # Parameters:.#.
0c80: 66 69 6c 65 4e 61 6d 65 20 2d 2d 20 4e 61 6d 65  fileName -- Name
0c90: 20 6f 66 20 74 68 65 20 74 69 6d 65 20 7a 6f 6e   of the time zon
0ca0: 65 20 73 6f 75 72 63 65 20 66 69 6c 65 2e 0a 23  e source file..#
0cb0: 0a 23 20 52 65 73 75 6c 74 73 3a 0a 23 09 4e 6f  .# Results:.#.No
0cc0: 6e 65 2e 0a 23 0a 23 20 53 69 64 65 20 65 66 66  ne..#.# Side eff
0cd0: 65 63 74 73 3a 0a 23 09 54 68 65 20 67 6c 6f 62  ects:.#.The glob
0ce0: 61 6c 20 76 61 72 69 61 62 6c 65 2c 20 27 65 72  al variable, 'er
0cf0: 72 6f 72 43 6f 75 6e 74 27 20 63 6f 75 6e 74 73  rorCount' counts
0d00: 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 65   the number of e
0d10: 72 72 6f 72 73 2e 0a 23 09 54 68 65 20 67 6c 6f  rrors..#.The glo
0d20: 62 61 6c 20 61 72 72 61 79 2c 20 27 6c 69 6e 6b  bal array, 'link
0d30: 73 27 2c 20 63 6f 6e 74 61 69 6e 73 20 61 20 64  s', contains a d
0d40: 69 73 74 69 6c 6c 61 74 69 6f 6e 20 6f 66 20 74  istillation of t
0d50: 68 65 0a 23 09 27 4c 69 6e 6b 27 20 64 69 72 65  he.#.'Link' dire
0d60: 63 74 69 76 65 73 20 69 6e 20 74 68 65 20 66 69  ctives in the fi
0d70: 6c 65 2e 20 54 68 65 20 6b 65 79 73 20 61 72 65  le. The keys are
0d80: 20 27 6c 69 6e 6b 73 20 74 6f 27 20 61 6e 64 0a   'links to' and.
0d90: 23 09 74 68 65 20 76 61 6c 75 65 73 20 61 72 65  #.the values are
0da0: 20 27 6c 69 6e 6b 73 20 66 72 6f 6d 27 2e 20 20   'links from'.  
0db0: 54 68 65 20 27 70 61 72 73 65 52 75 6c 65 27 20  The 'parseRule' 
0dc0: 61 6e 64 20 27 70 61 72 73 65 5a 6f 6e 65 27 0a  and 'parseZone'.
0dd0: 23 09 70 72 6f 63 65 64 75 72 65 73 20 61 72 65  #.procedures are
0de0: 20 63 61 6c 6c 65 64 20 74 6f 20 68 61 6e 64 6c   called to handl
0df0: 65 20 27 52 75 6c 65 27 20 61 6e 64 20 27 5a 6f  e 'Rule' and 'Zo
0e00: 6e 65 27 20 64 69 72 65 63 74 69 76 65 73 2e 0a  ne' directives..
0e10: 23 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  #.#-------------
0e20: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0e30: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0e40: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0e50: 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 0a 70 72 6f 63 20  ---------..proc 
0e60: 6c 6f 61 64 5a 49 43 20 7b 66 69 6c 65 4e 61 6d  loadZIC {fileNam
0e70: 65 7d 20 7b 0a 20 20 20 20 76 61 72 69 61 62 6c  e} {.    variabl
0e80: 65 20 65 72 72 6f 72 43 6f 75 6e 74 0a 20 20 20  e errorCount.   
0e90: 20 76 61 72 69 61 62 6c 65 20 6c 69 6e 6b 73 0a   variable links.
0ea0: 0a 20 20 20 20 23 20 53 75 63 6b 20 74 68 65 20  .    # Suck the 
0eb0: 74 65 78 74 20 69 6e 74 6f 20 6d 65 6d 6f 72 79  text into memory
0ec0: 2e 0a 0a 20 20 20 20 73 65 74 20 66 20 5b 6f 70  ...    set f [op
0ed0: 65 6e 20 24 66 69 6c 65 4e 61 6d 65 20 72 5d 0a  en $fileName r].
0ee0: 20 20 20 20 73 65 74 20 64 61 74 61 20 5b 72 65      set data [re
0ef0: 61 64 20 24 66 5d 0a 20 20 20 20 63 6c 6f 73 65  ad $f].    close
0f00: 20 24 66 0a 0a 20 20 20 20 23 20 42 72 65 61 6b   $f..    # Break
0f10: 20 74 68 65 20 69 6e 70 75 74 20 69 6e 74 6f 20   the input into 
0f20: 6c 69 6e 65 73 2c 20 61 6e 64 20 63 6f 75 6e 74  lines, and count
0f30: 20 6c 69 6e 65 20 6e 75 6d 62 65 72 73 2e 0a 0a   line numbers...
0f40: 20 20 20 20 73 65 74 20 6c 6e 6f 20 30 0a 20 20      set lno 0.  
0f50: 20 20 66 6f 72 65 61 63 68 20 6c 69 6e 65 20 5b    foreach line [
0f60: 73 70 6c 69 74 20 24 64 61 74 61 20 5c 6e 5d 20  split $data \n] 
0f70: 7b 0a 09 69 6e 63 72 20 6c 6e 6f 0a 0a 09 23 20  {..incr lno...# 
0f80: 42 72 65 61 6b 20 61 20 6c 69 6e 65 20 6f 66 20  Break a line of 
0f90: 69 6e 70 75 74 20 69 6e 74 6f 20 77 6f 72 64 73  input into words
0fa0: 2e 0a 0a 09 72 65 67 73 75 62 20 7b 5c 73 2a 28  ....regsub {\s*(
0fb0: 5c 23 2e 2a 29 3f 24 7d 20 24 6c 69 6e 65 20 7b  \#.*)?$} $line {
0fc0: 7d 20 6c 69 6e 65 0a 09 69 66 20 7b 24 6c 69 6e  } line..if {$lin
0fd0: 65 20 65 71 20 22 22 7d 20 7b 0a 09 20 20 20 20  e eq ""} {..    
0fe0: 63 6f 6e 74 69 6e 75 65 0a 09 7d 0a 09 73 65 74  continue..}..set
0ff0: 20 77 6f 72 64 73 20 7b 7d 0a 09 69 66 20 7b 5b   words {}..if {[
1000: 72 65 67 65 78 70 20 7b 5e 5c 73 7d 20 24 6c 69  regexp {^\s} $li
1010: 6e 65 5d 7d 20 7b 0a 09 20 20 20 20 23 20 44 65  ne]} {..    # De
1020: 74 65 63 74 20 63 6f 6e 74 69 6e 75 61 74 69 6f  tect continuatio
1030: 6e 73 20 6f 66 20 61 20 7a 6f 6e 65 20 61 6e 64  ns of a zone and
1040: 20 66 6c 61 67 20 74 68 65 20 6c 69 73 74 20 61   flag the list a
1050: 70 70 72 6f 70 72 69 61 74 65 6c 79 0a 09 20 20  ppropriately..  
1060: 20 20 6c 61 70 70 65 6e 64 20 77 6f 72 64 73 20    lappend words 
1070: 22 22 0a 09 7d 0a 09 6c 61 70 70 65 6e 64 20 77  ""..}..lappend w
1080: 6f 72 64 73 20 7b 2a 7d 5b 72 65 67 65 78 70 20  ords {*}[regexp 
1090: 2d 61 6c 6c 20 2d 69 6e 6c 69 6e 65 20 7b 5c 53  -all -inline {\S
10a0: 2b 7d 20 24 6c 69 6e 65 5d 0a 0a 09 23 20 53 77  +} $line]...# Sw
10b0: 69 74 63 68 20 6f 6e 20 74 68 65 20 64 69 72 65  itch on the dire
10c0: 63 74 69 76 65 0a 0a 09 73 77 69 74 63 68 20 2d  ctive...switch -
10d0: 65 78 61 63 74 20 2d 2d 20 5b 6c 69 6e 64 65 78  exact -- [lindex
10e0: 20 24 77 6f 72 64 73 20 30 5d 20 7b 0a 09 20 20   $words 0] {..  
10f0: 20 20 52 75 6c 65 20 7b 0a 09 09 70 61 72 73 65    Rule {...parse
1100: 52 75 6c 65 20 24 66 69 6c 65 4e 61 6d 65 20 24  Rule $fileName $
1110: 6c 6e 6f 20 24 77 6f 72 64 73 0a 09 20 20 20 20  lno $words..    
1120: 7d 0a 09 20 20 20 20 4c 69 6e 6b 20 7b 0a 09 09  }..    Link {...
1130: 73 65 74 20 6c 69 6e 6b 73 28 5b 6c 69 6e 64 65  set links([linde
1140: 78 20 24 77 6f 72 64 73 20 32 5d 29 20 5b 6c 69  x $words 2]) [li
1150: 6e 64 65 78 20 24 77 6f 72 64 73 20 31 5d 0a 09  ndex $words 1]..
1160: 20 20 20 20 7d 0a 09 20 20 20 20 5a 6f 6e 65 20      }..    Zone 
1170: 7b 0a 09 09 73 65 74 20 6c 61 73 74 5a 6f 6e 65  {...set lastZone
1180: 20 5b 6c 69 6e 64 65 78 20 24 77 6f 72 64 73 20   [lindex $words 
1190: 31 5d 0a 09 09 73 65 74 20 75 6e 74 69 6c 20 5b  1]...set until [
11a0: 70 61 72 73 65 5a 6f 6e 65 20 24 66 69 6c 65 4e  parseZone $fileN
11b0: 61 6d 65 20 24 6c 6e 6f 20 5c 0a 09 09 09 24 6c  ame $lno \....$l
11c0: 61 73 74 5a 6f 6e 65 20 5b 6c 72 61 6e 67 65 20  astZone [lrange 
11d0: 24 77 6f 72 64 73 20 32 20 65 6e 64 5d 20 22 6d  $words 2 end] "m
11e0: 69 6e 69 6d 75 6d 22 5d 0a 09 20 20 20 20 7d 0a  inimum"]..    }.
11f0: 09 20 20 20 20 7b 7d 20 7b 0a 09 09 73 65 74 20  .    {} {...set 
1200: 69 20 30 0a 09 09 66 6f 72 65 61 63 68 20 77 6f  i 0...foreach wo
1210: 72 64 20 24 77 6f 72 64 73 20 7b 0a 09 09 20 20  rd $words {...  
1220: 20 20 69 66 20 7b 5b 6c 69 6e 64 65 78 20 24 77    if {[lindex $w
1230: 6f 72 64 73 20 24 69 5d 20 6e 65 20 22 22 7d 20  ords $i] ne ""} 
1240: 7b 0a 09 09 09 62 72 65 61 6b 0a 09 09 20 20 20  {....break...   
1250: 20 7d 0a 09 09 20 20 20 20 69 6e 63 72 20 69 0a   }...    incr i.
1260: 09 09 7d 0a 09 09 73 65 74 20 77 6f 72 64 73 20  ..}...set words 
1270: 5b 6c 72 61 6e 67 65 20 24 77 6f 72 64 73 20 24  [lrange $words $
1280: 69 20 65 6e 64 5d 0a 09 09 73 65 74 20 75 6e 74  i end]...set unt
1290: 69 6c 20 5b 70 61 72 73 65 5a 6f 6e 65 20 24 66  il [parseZone $f
12a0: 69 6c 65 4e 61 6d 65 20 24 6c 6e 6f 20 24 6c 61  ileName $lno $la
12b0: 73 74 5a 6f 6e 65 20 24 77 6f 72 64 73 20 24 75  stZone $words $u
12c0: 6e 74 69 6c 5d 0a 09 20 20 20 20 7d 0a 09 20 20  ntil]..    }..  
12d0: 20 20 64 65 66 61 75 6c 74 20 7b 0a 09 09 69 6e    default {...in
12e0: 63 72 20 65 72 72 6f 72 43 6f 75 6e 74 0a 09 09  cr errorCount...
12f0: 70 75 74 73 20 73 74 64 65 72 72 20 22 24 66 69  puts stderr "$fi
1300: 6c 65 4e 61 6d 65 3a 24 6c 6e 6f 3a 75 6e 6b 6e  leName:$lno:unkn
1310: 6f 77 6e 20 6c 69 6e 65 20 74 79 70 65 20 5c 22  own line type \"
1320: 5b 6c 69 6e 64 65 78 20 24 77 6f 72 64 73 20 30  [lindex $words 0
1330: 5d 5c 22 22 0a 09 20 20 20 20 7d 0a 09 7d 0a 20  ]\""..    }..}. 
1340: 20 20 20 7d 0a 0a 20 20 20 20 72 65 74 75 72 6e     }..    return
1350: 0a 7d 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  .}..#-----------
1360: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1370: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1380: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1390: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 0a 23 20  -----------.#.# 
13a0: 70 61 72 73 65 52 75 6c 65 20 2d 2d 0a 23 0a 23  parseRule --.#.#
13b0: 09 50 61 72 73 65 73 20 61 20 52 75 6c 65 20 64  .Parses a Rule d
13c0: 69 72 65 63 74 69 76 65 20 69 6e 20 61 6e 20 4f  irective in an O
13d0: 6c 73 6f 6e 20 66 69 6c 65 2e 0a 23 0a 23 20 50  lson file..#.# P
13e0: 61 72 61 6d 65 74 65 72 73 3a 0a 23 09 66 69 6c  arameters:.#.fil
13f0: 65 4e 61 6d 65 20 2d 2d 20 4e 61 6d 65 20 6f 66  eName -- Name of
1400: 20 74 68 65 20 66 69 6c 65 20 62 65 69 6e 67 20   the file being 
1410: 70 61 72 73 65 64 2e 0a 23 09 6c 6e 6f 20 2d 20  parsed..#.lno - 
1420: 4c 69 6e 65 20 6e 75 6d 62 65 72 20 77 69 74 68  Line number with
1430: 69 6e 20 74 68 65 20 66 69 6c 65 0a 23 09 77 6f  in the file.#.wo
1440: 72 64 73 20 2d 20 54 68 65 20 6c 69 6e 65 20 69  rds - The line i
1450: 74 73 65 6c 66 2c 20 62 72 6f 6b 65 6e 20 69 6e  tself, broken in
1460: 74 6f 20 77 6f 72 64 73 2e 0a 23 0a 23 20 52 65  to words..#.# Re
1470: 73 75 6c 74 73 3a 0a 23 09 4e 6f 6e 65 2e 0a 23  sults:.#.None..#
1480: 0a 23 20 53 69 64 65 20 65 66 66 65 63 74 73 3a  .# Side effects:
1490: 0a 23 09 54 68 65 20 72 75 6c 65 20 69 73 20 61  .#.The rule is a
14a0: 6e 61 6c 79 7a 65 64 20 61 6e 64 20 61 64 64 65  nalyzed and adde
14b0: 64 20 74 6f 20 74 68 65 20 27 72 75 6c 65 73 27  d to the 'rules'
14c0: 20 61 72 72 61 79 2e 0a 23 09 45 72 72 6f 72 73   array..#.Errors
14d0: 20 61 72 65 20 72 65 70 6f 72 74 65 64 20 61 6e   are reported an
14e0: 64 20 63 6f 75 6e 74 65 64 2e 0a 23 0a 23 2d 2d  d counted..#.#--
14f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1500: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1510: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1520: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1530: 2d 2d 2d 2d 0a 0a 70 72 6f 63 20 70 61 72 73 65  ----..proc parse
1540: 52 75 6c 65 20 7b 66 69 6c 65 4e 61 6d 65 20 6c  Rule {fileName l
1550: 6e 6f 20 77 6f 72 64 73 7d 20 7b 0a 20 20 20 20  no words} {.    
1560: 76 61 72 69 61 62 6c 65 20 72 75 6c 65 73 0a 20  variable rules. 
1570: 20 20 20 76 61 72 69 61 62 6c 65 20 65 72 72 6f     variable erro
1580: 72 43 6f 75 6e 74 0a 0a 20 20 20 20 23 20 42 72  rCount..    # Br
1590: 65 61 6b 20 6f 75 74 20 74 68 65 20 63 6f 6c 75  eak out the colu
15a0: 6d 6e 73 0a 0a 20 20 20 20 6c 61 73 73 69 67 6e  mns..    lassign
15b0: 20 24 77 6f 72 64 73 20 20 52 75 6c 65 20 6e 61   $words  Rule na
15c0: 6d 65 20 66 72 6f 6d 20 74 6f 20 74 79 70 65 20  me from to type 
15d0: 69 6e 20 6f 6e 20 61 74 20 73 61 76 65 20 6c 65  in on at save le
15e0: 74 74 65 72 0a 0a 20 20 20 20 23 20 48 61 6e 64  tter..    # Hand
15f0: 6c 65 20 74 68 65 20 27 6f 6e 6c 79 27 20 6b 65  le the 'only' ke
1600: 79 77 6f 72 64 0a 0a 20 20 20 20 69 66 20 7b 24  yword..    if {$
1610: 74 6f 20 65 71 20 22 6f 6e 6c 79 22 7d 20 7b 0a  to eq "only"} {.
1620: 09 73 65 74 20 74 6f 20 24 66 72 6f 6d 0a 20 20  .set to $from.  
1630: 20 20 7d 0a 0a 20 20 20 20 23 20 50 72 6f 63 65    }..    # Proce
1640: 73 73 20 74 68 65 20 73 74 61 72 74 20 79 65 61  ss the start yea
1650: 72 0a 0a 20 20 20 20 69 66 20 7b 21 5b 73 74 72  r..    if {![str
1660: 69 6e 67 20 69 73 20 69 6e 74 65 67 65 72 20 24  ing is integer $
1670: 66 72 6f 6d 5d 7d 20 7b 0a 09 69 66 20 7b 21 5b  from]} {..if {![
1680: 73 74 72 69 6e 67 20 65 71 75 61 6c 20 2d 6c 65  string equal -le
1690: 6e 67 74 68 20 5b 73 74 72 69 6e 67 20 6c 65 6e  ngth [string len
16a0: 67 74 68 20 24 66 72 6f 6d 5d 20 24 66 72 6f 6d  gth $from] $from
16b0: 20 22 6d 69 6e 69 6d 75 6d 22 5d 7d 20 7b 0a 09   "minimum"]} {..
16c0: 20 20 20 20 70 75 74 73 20 73 74 64 65 72 72 20      puts stderr 
16d0: 22 24 66 69 6c 65 4e 61 6d 65 3a 24 6c 6e 6f 3a  "$fileName:$lno:
16e0: 46 52 4f 4d 20 66 69 65 6c 64 20 5c 22 24 66 72  FROM field \"$fr
16f0: 6f 6d 5c 22 20 6e 6f 74 20 61 6e 20 69 6e 74 65  om\" not an inte
1700: 67 65 72 2e 22 0a 09 20 20 20 20 69 6e 63 72 20  ger."..    incr 
1710: 65 72 72 6f 72 43 6f 75 6e 74 0a 09 20 20 20 20  errorCount..    
1720: 72 65 74 75 72 6e 0a 09 7d 20 65 6c 73 65 20 7b  return..} else {
1730: 0a 09 20 20 20 20 73 65 74 20 66 72 6f 6d 20 22  ..    set from "
1740: 6d 69 6e 69 6d 75 6d 22 0a 09 7d 0a 20 20 20 20  minimum"..}.    
1750: 7d 0a 0a 20 20 20 20 23 20 50 72 6f 63 65 73 73  }..    # Process
1760: 20 74 68 65 20 65 6e 64 20 79 65 61 72 0a 0a 20   the end year.. 
1770: 20 20 20 69 66 20 7b 21 5b 73 74 72 69 6e 67 20     if {![string 
1780: 69 73 20 69 6e 74 65 67 65 72 20 24 74 6f 5d 7d  is integer $to]}
1790: 20 7b 0a 09 69 66 20 7b 21 5b 73 74 72 69 6e 67   {..if {![string
17a0: 20 65 71 75 61 6c 20 2d 6c 65 6e 67 74 68 20 5b   equal -length [
17b0: 73 74 72 69 6e 67 20 6c 65 6e 67 74 68 20 24 74  string length $t
17c0: 6f 5d 20 24 74 6f 20 22 6d 61 78 69 6d 75 6d 22  o] $to "maximum"
17d0: 5d 7d 20 7b 0a 09 20 20 20 20 70 75 74 73 20 73  ]} {..    puts s
17e0: 74 64 65 72 72 20 22 24 66 69 6c 65 4e 61 6d 65  tderr "$fileName
17f0: 3a 24 6c 6e 6f 3a 54 4f 20 66 69 65 6c 64 20 5c  :$lno:TO field \
1800: 22 24 74 6f 5c 22 20 6e 6f 74 20 61 6e 20 69 6e  "$to\" not an in
1810: 74 65 67 65 72 2e 22 0a 09 20 20 20 20 69 6e 63  teger."..    inc
1820: 72 20 65 72 72 6f 72 43 6f 75 6e 74 0a 09 20 20  r errorCount..  
1830: 20 20 72 65 74 75 72 6e 0a 09 7d 20 65 6c 73 65    return..} else
1840: 20 7b 0a 09 20 20 20 20 73 65 74 20 74 6f 20 22   {..    set to "
1850: 6d 61 78 69 6d 75 6d 22 0a 09 7d 0a 20 20 20 20  maximum"..}.    
1860: 7d 0a 0a 20 20 20 20 23 20 50 72 6f 63 65 73 73  }..    # Process
1870: 20 74 68 65 20 74 79 70 65 20 6f 66 20 79 65 61   the type of yea
1880: 72 20 69 6e 20 77 68 69 63 68 20 74 68 65 20 72  r in which the r
1890: 75 6c 65 20 61 70 70 6c 69 65 73 0a 0a 20 20 20  ule applies..   
18a0: 20 69 66 20 7b 24 74 79 70 65 20 6e 65 20 22 2d   if {$type ne "-
18b0: 22 7d 20 7b 0a 09 70 75 74 73 20 73 74 64 65 72  "} {..puts stder
18c0: 72 20 22 24 66 69 6c 65 4e 61 6d 65 3a 24 6c 6e  r "$fileName:$ln
18d0: 6f 3a 79 65 61 72 20 74 79 70 65 73 20 61 72 65  o:year types are
18e0: 20 6e 6f 74 20 79 65 74 20 73 75 70 70 6f 72 74   not yet support
18f0: 65 64 2e 22 0a 09 69 6e 63 72 20 65 72 72 6f 72  ed."..incr error
1900: 43 6f 75 6e 74 0a 09 72 65 74 75 72 6e 0a 20 20  Count..return.  
1910: 20 20 7d 0a 0a 20 20 20 20 23 20 50 72 6f 63 65    }..    # Proce
1920: 73 73 20 74 68 65 20 6d 6f 6e 74 68 20 69 6e 20  ss the month in 
1930: 77 68 69 63 68 20 74 68 65 20 72 75 6c 65 20 73  which the rule s
1940: 74 61 72 74 73 0a 0a 20 20 20 20 69 66 20 7b 5b  tarts..    if {[
1950: 63 61 74 63 68 20 7b 6c 6f 6f 6b 75 70 4d 6f 6e  catch {lookupMon
1960: 74 68 20 24 69 6e 7d 20 69 6e 5d 7d 20 7b 0a 09  th $in} in]} {..
1970: 70 75 74 73 20 73 74 64 65 72 72 20 22 24 66 69  puts stderr "$fi
1980: 6c 65 4e 61 6d 65 3a 24 6c 6e 6f 3a 24 69 6e 22  leName:$lno:$in"
1990: 0a 09 69 6e 63 72 20 65 72 72 6f 72 43 6f 75 6e  ..incr errorCoun
19a0: 74 0a 09 72 65 74 75 72 6e 0a 20 20 20 20 7d 0a  t..return.    }.
19b0: 0a 20 20 20 20 23 20 50 72 6f 63 65 73 73 20 74  .    # Process t
19c0: 68 65 20 64 61 79 20 6f 66 20 74 68 65 20 6d 6f  he day of the mo
19d0: 6e 74 68 20 6f 6e 20 77 68 69 63 68 20 74 68 65  nth on which the
19e0: 20 72 75 6c 65 20 73 74 61 72 74 73 0a 0a 20 20   rule starts..  
19f0: 20 20 69 66 20 7b 5b 63 61 74 63 68 20 7b 70 61    if {[catch {pa
1a00: 72 73 65 4f 4e 20 24 6f 6e 7d 20 6f 6e 5d 7d 20  rseON $on} on]} 
1a10: 7b 0a 09 70 75 74 73 20 73 74 64 65 72 72 20 22  {..puts stderr "
1a20: 24 66 69 6c 65 4e 61 6d 65 3a 24 6c 6e 6f 3a 24  $fileName:$lno:$
1a30: 6f 6e 22 0a 09 69 6e 63 72 20 65 72 72 6f 72 43  on"..incr errorC
1a40: 6f 75 6e 74 0a 09 72 65 74 75 72 6e 0a 20 20 20  ount..return.   
1a50: 20 7d 0a 0a 20 20 20 20 23 20 50 72 6f 63 65 73   }..    # Proces
1a60: 73 20 74 68 65 20 74 69 6d 65 20 6f 66 20 64 61  s the time of da
1a70: 79 20 6f 6e 20 77 68 69 63 68 20 74 68 65 20 72  y on which the r
1a80: 75 6c 65 20 73 74 61 72 74 73 0a 0a 20 20 20 20  ule starts..    
1a90: 69 66 20 7b 5b 63 61 74 63 68 20 7b 70 61 72 73  if {[catch {pars
1aa0: 65 54 4f 44 20 24 61 74 7d 20 61 74 5d 7d 20 7b  eTOD $at} at]} {
1ab0: 0a 09 70 75 74 73 20 73 74 64 65 72 72 20 22 24  ..puts stderr "$
1ac0: 66 69 6c 65 4e 61 6d 65 3a 24 6c 6e 6f 3a 24 61  fileName:$lno:$a
1ad0: 74 22 0a 09 69 6e 63 72 20 65 72 72 6f 72 43 6f  t"..incr errorCo
1ae0: 75 6e 74 0a 09 72 65 74 75 72 6e 0a 20 20 20 20  unt..return.    
1af0: 7d 0a 0a 20 20 20 20 23 20 50 72 6f 63 65 73 73  }..    # Process
1b00: 20 74 68 65 20 44 53 54 20 61 64 64 65 72 0a 0a   the DST adder..
1b10: 20 20 20 20 69 66 20 7b 5b 63 61 74 63 68 20 7b      if {[catch {
1b20: 70 61 72 73 65 4f 66 66 73 65 74 54 69 6d 65 20  parseOffsetTime 
1b30: 24 73 61 76 65 7d 20 73 61 76 65 5d 7d 20 7b 0a  $save} save]} {.
1b40: 09 70 75 74 73 20 73 74 64 65 72 72 20 22 24 66  .puts stderr "$f
1b50: 69 6c 65 4e 61 6d 65 3a 24 6c 6e 6f 3a 24 73 61  ileName:$lno:$sa
1b60: 76 65 22 0a 09 69 6e 63 72 20 65 72 72 6f 72 43  ve"..incr errorC
1b70: 6f 75 6e 74 0a 09 72 65 74 75 72 6e 0a 20 20 20  ount..return.   
1b80: 20 7d 0a 0a 20 20 20 20 23 20 50 72 6f 63 65 73   }..    # Proces
1b90: 73 20 74 68 65 20 6c 65 74 74 65 72 20 74 6f 20  s the letter to 
1ba0: 75 73 65 20 66 6f 72 20 73 75 6d 6d 65 72 20 74  use for summer t
1bb0: 69 6d 65 0a 0a 20 20 20 20 69 66 20 7b 24 6c 65  ime..    if {$le
1bc0: 74 74 65 72 20 65 71 20 22 2d 22 7d 20 7b 0a 09  tter eq "-"} {..
1bd0: 73 65 74 20 6c 65 74 74 65 72 20 22 22 0a 20 20  set letter "".  
1be0: 20 20 7d 0a 0a 20 20 20 20 23 20 41 63 63 75 6d    }..    # Accum
1bf0: 75 6c 61 74 65 20 61 6c 6c 20 74 68 65 20 64 61  ulate all the da
1c00: 74 61 2e 0a 0a 20 20 20 20 6c 61 70 70 65 6e 64  ta...    lappend
1c10: 20 72 75 6c 65 73 28 24 6e 61 6d 65 29 20 24 66   rules($name) $f
1c20: 72 6f 6d 20 24 74 6f 20 24 74 79 70 65 20 24 69  rom $to $type $i
1c30: 6e 20 24 6f 6e 20 24 61 74 20 24 73 61 76 65 20  n $on $at $save 
1c40: 24 6c 65 74 74 65 72 0a 20 20 20 20 72 65 74 75  $letter.    retu
1c50: 72 6e 0a 0a 7d 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d  rn..}..#--------
1c60: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1c70: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1c80: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1c90: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23  --------------.#
1ca0: 0a 23 20 70 61 72 73 65 4f 4e 20 2d 2d 0a 23 0a  .# parseON --.#.
1cb0: 23 09 50 61 72 73 65 20 61 20 73 70 65 63 69 66  #.Parse a specif
1cc0: 69 63 61 74 69 6f 6e 20 66 6f 72 20 61 20 64 61  ication for a da
1cd0: 79 20 6f 66 20 74 68 65 20 6d 6f 6e 74 68 0a 23  y of the month.#
1ce0: 0a 23 20 50 61 72 61 6d 65 74 65 72 73 3a 0a 23  .# Parameters:.#
1cf0: 09 6f 6e 20 2d 20 74 68 65 20 4f 4e 20 66 69 65  .on - the ON fie
1d00: 6c 64 20 66 72 6f 6d 20 61 20 6c 69 6e 65 20 69  ld from a line i
1d10: 6e 20 61 6e 20 4f 6c 73 6f 6e 20 66 69 6c 65 2e  n an Olson file.
1d20: 0a 23 0a 23 20 52 65 73 75 6c 74 73 3a 0a 23 09  .#.# Results:.#.
1d30: 52 65 74 75 72 6e 73 20 61 20 70 61 72 74 69 61  Returns a partia
1d40: 6c 20 54 63 6c 20 63 6f 6d 6d 61 6e 64 2e 09 57  l Tcl command..W
1d50: 68 65 6e 20 74 68 65 20 79 65 61 72 20 61 6e 64  hen the year and
1d60: 20 6e 75 6d 62 65 72 20 6f 66 20 74 68 65 0a 23   number of the.#
1d70: 09 6d 6f 6e 74 68 20 61 72 65 20 61 70 70 65 6e  .month are appen
1d80: 64 65 64 2c 20 74 68 65 20 63 6f 6d 6d 61 6e 64  ded, the command
1d90: 20 77 69 6c 6c 20 72 65 74 75 72 6e 20 74 68 65   will return the
1da0: 20 4a 75 6c 69 61 6e 20 44 61 79 20 4e 75 6d 62   Julian Day Numb
1db0: 65 72 0a 23 09 6f 66 20 74 68 65 20 64 65 73 69  er.#.of the desi
1dc0: 72 65 64 20 64 61 74 65 2e 0a 23 0a 23 20 53 69  red date..#.# Si
1dd0: 64 65 20 65 66 66 65 63 74 73 3a 0a 23 09 4e 6f  de effects:.#.No
1de0: 6e 65 2e 0a 23 0a 23 20 54 68 65 20 73 70 65 63  ne..#.# The spec
1df0: 69 66 69 63 61 74 69 6f 6e 20 63 61 6e 20 62 65  ification can be
1e00: 3a 0a 23 09 2d 20 61 20 73 69 6d 70 6c 65 20 6e  :.#.- a simple n
1e10: 75 6d 62 65 72 2c 20 77 68 69 63 68 20 64 65 73  umber, which des
1e20: 69 67 6e 61 74 65 73 20 61 20 63 6f 6e 73 74 61  ignates a consta
1e30: 6e 74 20 64 61 74 65 2e 0a 23 09 2d 20 54 68 65  nt date..#.- The
1e40: 20 6e 61 6d 65 20 6f 66 20 61 20 77 65 65 6b 64   name of a weekd
1e50: 61 79 2c 20 66 6f 6c 6c 6f 77 65 64 20 62 79 20  ay, followed by 
1e60: 3e 3d 20 6f 72 20 3c 3d 2c 20 66 6f 6c 6c 6f 77  >= or <=, follow
1e70: 65 64 20 62 79 20 61 20 6e 75 6d 62 65 72 2e 0a  ed by a number..
1e80: 23 09 20 20 20 20 54 68 69 73 20 64 65 73 69 67  #.    This desig
1e90: 6e 61 74 65 73 20 74 68 65 20 6e 65 61 72 65 73  nates the neares
1ea0: 74 20 6f 63 63 75 72 72 65 6e 63 65 20 6f 66 20  t occurrence of 
1eb0: 74 68 65 20 67 69 76 65 6e 20 77 65 65 6b 64 61  the given weekda
1ec0: 79 20 6f 6e 0a 23 09 20 20 20 20 6f 72 20 62 65  y on.#.    or be
1ed0: 66 6f 72 65 20 28 6f 6e 20 6f 72 20 61 66 74 65  fore (on or afte
1ee0: 72 29 20 74 68 65 20 67 69 76 65 6e 20 64 61 79  r) the given day
1ef0: 20 6f 66 20 74 68 65 20 6d 6f 6e 74 68 2e 0a 23   of the month..#
1f00: 09 2d 20 54 68 65 20 77 6f 72 64 20 27 6c 61 73  .- The word 'las
1f10: 74 27 20 66 6f 6c 6c 6f 77 65 64 20 62 79 20 61  t' followed by a
1f20: 20 77 65 65 6b 64 61 79 20 6e 61 6d 65 20 77 69   weekday name wi
1f30: 74 68 20 6e 6f 20 69 6e 74 65 72 76 65 6e 69 6e  th no intervenin
1f40: 67 0a 23 09 20 20 73 70 61 63 65 2e 20 20 54 68  g.#.  space.  Th
1f50: 69 73 20 64 65 73 69 67 6e 61 74 65 73 20 74 68  is designates th
1f60: 65 20 6c 61 73 74 20 6f 63 63 75 72 72 65 6e 63  e last occurrenc
1f70: 65 20 6f 66 20 74 68 65 20 67 69 76 65 6e 20 77  e of the given w
1f80: 65 65 6b 64 61 79 0a 23 09 20 20 69 6e 20 74 68  eekday.#.  in th
1f90: 65 20 6d 6f 6e 74 68 2e 0a 23 0a 23 2d 2d 2d 2d  e month..#.#----
1fa0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1fb0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1fc0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1fd0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1fe0: 2d 2d 0a 0a 70 72 6f 63 20 70 61 72 73 65 4f 4e  --..proc parseON
1ff0: 20 7b 6f 6e 7d 20 7b 0a 20 20 20 20 69 66 20 7b   {on} {.    if {
2000: 21 5b 72 65 67 65 78 70 20 2d 65 78 70 61 6e 64  ![regexp -expand
2010: 65 64 20 7b 0a 09 5e 28 3f 3a 0a 09 20 20 23 20  ed {..^(?:..  # 
2020: 66 69 72 73 74 20 70 6f 73 73 69 62 69 6c 69 74  first possibilit
2030: 79 20 2d 20 73 69 6d 70 6c 65 20 6e 75 6d 62 65  y - simple numbe
2040: 72 20 2d 20 66 69 65 6c 64 20 31 0a 09 20 20 28  r - field 1..  (
2050: 5b 5b 3a 64 69 67 69 74 3a 5d 5d 2b 29 0a 09 7c  [[:digit:]]+)..|
2060: 0a 09 20 20 23 20 73 65 63 6f 6e 64 20 70 6f 73  ..  # second pos
2070: 73 69 62 69 6c 69 74 79 20 2d 20 77 65 65 6b 64  sibility - weekd
2080: 61 79 20 3e 3d 20 28 6f 72 20 3c 3d 29 20 6e 75  ay >= (or <=) nu
2090: 6d 62 65 72 0a 09 20 20 23 20 66 69 65 6c 64 20  mber..  # field 
20a0: 32 20 2d 20 77 65 65 6b 64 61 79 0a 09 20 20 28  2 - weekday..  (
20b0: 5b 5b 3a 61 6c 70 68 61 3a 5d 5d 2b 29 0a 09 20  [[:alpha:]]+).. 
20c0: 20 23 20 66 69 65 6c 64 20 33 20 2d 20 64 69 72   # field 3 - dir
20d0: 65 63 74 69 6f 6e 0a 09 20 20 28 5b 3c 3e 5d 3d  ection..  ([<>]=
20e0: 29 0a 09 20 20 23 20 66 69 65 6c 64 20 34 20 2d  )..  # field 4 -
20f0: 20 6e 75 6d 62 65 72 0a 09 20 20 28 5b 5b 3a 64   number..  ([[:d
2100: 69 67 69 74 3a 5d 5d 2b 29 0a 09 7c 0a 09 20 20  igit:]]+)..|..  
2110: 23 20 74 68 69 72 64 20 70 6f 73 73 69 62 69 6c  # third possibil
2120: 69 74 79 20 2d 20 6c 61 73 74 57 65 65 6b 64 61  ity - lastWeekda
2130: 79 20 2d 20 66 69 65 6c 64 20 35 0a 09 20 20 6c  y - field 5..  l
2140: 61 73 74 28 5b 5b 3a 61 6c 70 68 61 3a 5d 5d 2b  ast([[:alpha:]]+
2150: 29 0a 09 29 24 0a 20 20 20 20 7d 20 24 6f 6e 20  )..)$.    } $on 
2160: 2d 3e 20 64 6f 6d 31 20 77 64 61 79 32 20 64 69  -> dom1 wday2 di
2170: 72 32 20 6e 75 6d 32 20 77 64 61 79 33 5d 7d 20  r2 num2 wday3]} 
2180: 7b 0a 09 65 72 72 6f 72 20 22 63 61 6e 27 74 20  {..error "can't 
2190: 70 61 72 73 65 20 4f 4e 20 66 69 65 6c 64 20 5c  parse ON field \
21a0: 22 24 6f 6e 5c 22 22 0a 20 20 20 20 7d 0a 20 20  "$on\"".    }.  
21b0: 20 20 69 66 20 7b 24 64 6f 6d 31 20 6e 65 20 22    if {$dom1 ne "
21c0: 22 7d 20 7b 0a 09 72 65 74 75 72 6e 20 5b 6c 69  "} {..return [li
21d0: 73 74 20 6f 6e 44 61 79 4f 66 4d 6f 6e 74 68 20  st onDayOfMonth 
21e0: 24 64 6f 6d 31 5d 0a 20 20 20 20 7d 20 65 6c 73  $dom1].    } els
21f0: 65 69 66 20 7b 24 77 64 61 79 32 20 6e 65 20 22  eif {$wday2 ne "
2200: 22 7d 20 7b 0a 09 73 65 74 20 77 64 61 79 32 20  "} {..set wday2 
2210: 5b 6c 6f 6f 6b 75 70 44 61 79 4f 66 57 65 65 6b  [lookupDayOfWeek
2220: 20 24 77 64 61 79 32 5d 0a 09 72 65 74 75 72 6e   $wday2]..return
2230: 20 5b 6c 69 73 74 20 6f 6e 57 65 65 6b 64 61 79   [list onWeekday
2240: 49 6e 4d 6f 6e 74 68 20 24 77 64 61 79 32 20 24  InMonth $wday2 $
2250: 64 69 72 32 20 24 6e 75 6d 32 5d 0a 20 20 20 20  dir2 $num2].    
2260: 7d 20 65 6c 73 65 69 66 20 7b 24 77 64 61 79 33  } elseif {$wday3
2270: 20 6e 65 20 22 22 7d 20 7b 0a 09 73 65 74 20 77   ne ""} {..set w
2280: 64 61 79 33 20 5b 6c 6f 6f 6b 75 70 44 61 79 4f  day3 [lookupDayO
2290: 66 57 65 65 6b 20 24 77 64 61 79 33 5d 0a 09 72  fWeek $wday3]..r
22a0: 65 74 75 72 6e 20 5b 6c 69 73 74 20 6f 6e 4c 61  eturn [list onLa
22b0: 73 74 57 65 65 6b 64 61 79 49 6e 4d 6f 6e 74 68  stWeekdayInMonth
22c0: 20 24 77 64 61 79 33 5d 0a 20 20 20 20 7d 20 65   $wday3].    } e
22d0: 6c 73 65 20 7b 0a 09 65 72 72 6f 72 20 22 69 6e  lse {..error "in
22e0: 20 70 61 72 73 65 4f 6e 20 5c 22 24 6f 6e 5c 22   parseOn \"$on\"
22f0: 3a 20 63 61 6e 27 74 20 68 61 70 70 65 6e 22 0a  : can't happen".
2300: 20 20 20 20 7d 0a 7d 0a 0a 23 2d 2d 2d 2d 2d 2d      }.}..#------
2310: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2320: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2330: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2340: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2350: 0a 23 0a 23 20 6f 6e 44 61 79 4f 66 4d 6f 6e 74  .#.# onDayOfMont
2360: 68 20 2d 2d 0a 23 0a 23 09 46 69 6e 64 20 61 20  h --.#.#.Find a 
2370: 67 69 76 65 6e 20 64 61 79 20 6f 66 20 61 20 67  given day of a g
2380: 69 76 65 6e 20 6d 6f 6e 74 68 0a 23 0a 23 20 50  iven month.#.# P
2390: 61 72 61 6d 65 74 65 72 73 3a 0a 23 09 64 61 79  arameters:.#.day
23a0: 20 2d 20 44 61 79 20 6f 66 20 74 68 65 20 6d 6f   - Day of the mo
23b0: 6e 74 68 0a 23 09 79 65 61 72 20 2d 20 47 72 65  nth.#.year - Gre
23c0: 67 6f 72 69 61 6e 20 79 65 61 72 0a 23 09 6d 6f  gorian year.#.mo
23d0: 6e 74 68 20 2d 20 4e 75 6d 62 65 72 20 6f 66 20  nth - Number of 
23e0: 74 68 65 20 6d 6f 6e 74 68 20 28 31 2d 31 32 29  the month (1-12)
23f0: 0a 23 0a 23 20 52 65 73 75 6c 74 73 3a 0a 23 09  .#.# Results:.#.
2400: 52 65 74 75 72 6e 73 20 74 68 65 20 4a 75 6c 69  Returns the Juli
2410: 61 6e 20 44 61 79 20 4e 75 6d 62 65 72 20 6f 66  an Day Number of
2420: 20 74 68 65 20 64 65 73 69 72 65 64 20 64 61 79   the desired day
2430: 2e 0a 23 0a 23 20 53 69 64 65 20 65 66 66 65 63  ..#.# Side effec
2440: 74 73 3a 0a 23 09 4e 6f 6e 65 2e 0a 23 0a 23 2d  ts:.#.None..#.#-
2450: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2460: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2470: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2480: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2490: 2d 2d 2d 2d 2d 0a 0a 70 72 6f 63 20 6f 6e 44 61  -----..proc onDa
24a0: 79 4f 66 4d 6f 6e 74 68 20 7b 64 61 79 20 79 65  yOfMonth {day ye
24b0: 61 72 20 6d 6f 6e 74 68 7d 20 7b 0a 20 20 20 20  ar month} {.    
24c0: 73 63 61 6e 20 24 64 61 79 20 25 64 20 64 61 79  scan $day %d day
24d0: 0a 20 20 20 20 73 63 61 6e 20 24 79 65 61 72 20  .    scan $year 
24e0: 25 64 20 79 65 61 72 0a 20 20 20 20 73 63 61 6e  %d year.    scan
24f0: 20 24 6d 6f 6e 74 68 20 25 64 20 6d 6f 6e 74 68   $month %d month
2500: 0a 20 20 20 20 73 65 74 20 64 61 74 65 20 5b 3a  .    set date [:
2510: 3a 74 63 6c 3a 3a 63 6c 6f 63 6b 3a 3a 47 65 74  :tcl::clock::Get
2520: 4a 75 6c 69 61 6e 44 61 79 46 72 6f 6d 45 72 61  JulianDayFromEra
2530: 59 65 61 72 4d 6f 6e 74 68 44 61 79 20 5c 0a 09  YearMonthDay \..
2540: 20 20 20 20 5b 64 69 63 74 20 63 72 65 61 74 65      [dict create
2550: 20 65 72 61 20 43 45 20 79 65 61 72 20 24 79 65   era CE year $ye
2560: 61 72 20 6d 6f 6e 74 68 20 24 6d 6f 6e 74 68 20  ar month $month 
2570: 64 61 79 4f 66 4d 6f 6e 74 68 20 24 64 61 79 5d  dayOfMonth $day]
2580: 20 5c 0a 09 09 20 32 33 36 31 32 32 32 5d 0a 20   \... 2361222]. 
2590: 20 20 20 72 65 74 75 72 6e 20 5b 64 69 63 74 20     return [dict 
25a0: 67 65 74 20 24 64 61 74 65 20 6a 75 6c 69 61 6e  get $date julian
25b0: 44 61 79 5d 0a 7d 0a 0a 23 2d 2d 2d 2d 2d 2d 2d  Day].}..#-------
25c0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
25d0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
25e0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
25f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a  ---------------.
2600: 23 0a 23 20 6f 6e 57 65 65 6b 64 61 79 49 6e 4d  #.# onWeekdayInM
2610: 6f 6e 74 68 20 2d 2d 0a 23 0a 23 09 46 69 6e 64  onth --.#.#.Find
2620: 20 74 68 65 20 77 65 65 6b 64 61 79 20 66 61 6c   the weekday fal
2630: 6c 69 6e 67 20 6f 6e 20 6f 72 20 61 66 74 65 72  ling on or after
2640: 20 28 6f 6e 20 6f 72 20 62 65 66 6f 72 65 29 20   (on or before) 
2650: 61 0a 23 09 67 69 76 65 6e 20 64 61 79 20 6f 66  a.#.given day of
2660: 20 74 68 65 20 6d 6f 6e 74 68 0a 23 0a 23 20 50   the month.#.# P
2670: 61 72 61 6d 65 74 65 72 73 3a 0a 23 09 64 61 79  arameters:.#.day
2680: 4f 66 57 65 65 6b 20 2d 20 44 61 79 20 6f 66 20  OfWeek - Day of 
2690: 74 68 65 20 77 65 65 6b 20 28 4d 6f 6e 64 61 79  the week (Monday
26a0: 3d 31 2c 20 53 75 6e 64 61 79 3d 37 29 0a 23 09  =1, Sunday=7).#.
26b0: 72 65 6c 61 74 69 6f 6e 20 2d 20 3c 3d 20 66 6f  relation - <= fo
26c0: 72 20 74 68 65 20 77 65 65 6b 64 61 79 20 6f 6e  r the weekday on
26d0: 20 6f 72 20 62 65 66 6f 72 65 20 61 20 67 69 76   or before a giv
26e0: 65 6e 20 64 61 74 65 2c 20 3e 3d 20 66 6f 72 0a  en date, >= for.
26f0: 23 09 09 20 20 20 74 68 65 20 77 65 65 6b 64 61  #..   the weekda
2700: 79 20 6f 6e 20 6f 72 20 61 66 74 65 72 20 74 68  y on or after th
2710: 65 20 67 69 76 65 6e 20 64 61 74 65 2e 0a 23 09  e given date..#.
2720: 64 61 79 4f 66 4d 6f 6e 74 68 20 2d 20 44 61 79  dayOfMonth - Day
2730: 20 6f 66 20 74 68 65 20 6d 6f 6e 74 68 0a 23 09   of the month.#.
2740: 79 65 61 72 20 2d 20 47 72 65 67 6f 72 69 61 6e  year - Gregorian
2750: 20 79 65 61 72 0a 23 09 6d 6f 6e 74 68 20 2d 20   year.#.month - 
2760: 4e 75 6d 62 65 72 20 6f 66 20 74 68 65 20 6d 6f  Number of the mo
2770: 6e 74 68 20 28 31 2d 31 32 29 0a 23 0a 23 20 52  nth (1-12).#.# R
2780: 65 73 75 6c 74 73 3a 0a 23 09 52 65 74 75 72 6e  esults:.#.Return
2790: 73 20 74 68 65 20 4a 75 6c 6f 61 6e 20 44 61 79  s the Juloan Day
27a0: 20 4e 75 6d 62 65 72 20 6f 66 20 74 68 65 20 64   Number of the d
27b0: 65 73 69 72 65 64 20 64 61 79 2e 0a 23 0a 23 20  esired day..#.# 
27c0: 53 69 64 65 20 65 66 66 65 63 74 73 3a 0a 23 09  Side effects:.#.
27d0: 4e 6f 6e 65 2e 0a 23 0a 23 20 6f 6e 57 65 65 6b  None..#.# onWeek
27e0: 64 61 79 49 6e 4d 6f 6e 74 68 20 69 73 20 75 73  dayInMonth is us
27f0: 65 64 20 74 6f 20 63 6f 6d 70 75 74 65 20 44 61  ed to compute Da
2800: 79 6c 69 67 68 74 20 53 61 76 69 6e 67 20 54 69  ylight Saving Ti
2810: 6d 65 20 72 75 6c 65 73 0a 23 20 6c 69 6b 65 20  me rules.# like 
2820: 27 53 75 6e 3e 3d 31 27 20 28 66 6f 72 20 74 68  'Sun>=1' (for th
2830: 65 20 6e 65 61 72 65 73 74 20 53 75 6e 64 61 79  e nearest Sunday
2840: 20 6f 6e 20 6f 72 20 61 66 74 65 72 20 74 68 65   on or after the
2850: 20 66 69 72 73 74 20 6f 66 20 74 68 65 20 6d 6f   first of the mo
2860: 6e 74 68 29 0a 23 20 6f 72 20 22 4d 6f 6e 3c 3d  nth).# or "Mon<=
2870: 34 27 20 28 66 6f 72 20 74 68 65 20 4d 6f 6e 64  4' (for the Mond
2880: 61 79 20 6f 6e 20 6f 72 20 62 65 66 6f 72 65 20  ay on or before 
2890: 74 68 65 20 66 6f 75 72 74 68 20 6f 66 20 74 68  the fourth of th
28a0: 65 20 6d 6f 6e 74 68 29 2e 0a 23 0a 23 2d 2d 2d  e month)..#.#---
28b0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
28c0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
28d0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
28e0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
28f0: 2d 2d 2d 0a 0a 70 72 6f 63 20 6f 6e 57 65 65 6b  ---..proc onWeek
2900: 64 61 79 49 6e 4d 6f 6e 74 68 20 7b 64 61 79 4f  dayInMonth {dayO
2910: 66 57 65 65 6b 20 72 65 6c 61 74 69 6f 6e 20 64  fWeek relation d
2920: 61 79 4f 66 4d 6f 6e 74 68 20 79 65 61 72 20 6d  ayOfMonth year m
2930: 6f 6e 74 68 7d 20 7b 0a 20 20 20 20 73 65 74 20  onth} {.    set 
2940: 64 61 74 65 20 5b 3a 3a 74 63 6c 3a 3a 63 6c 6f  date [::tcl::clo
2950: 63 6b 3a 3a 47 65 74 4a 75 6c 69 61 6e 44 61 79  ck::GetJulianDay
2960: 46 72 6f 6d 45 72 61 59 65 61 72 4d 6f 6e 74 68  FromEraYearMonth
2970: 44 61 79 20 5b 64 69 63 74 20 63 72 65 61 74 65  Day [dict create
2980: 20 5c 0a 09 20 20 20 20 65 72 61 20 43 45 20 79   \..    era CE y
2990: 65 61 72 20 24 79 65 61 72 20 6d 6f 6e 74 68 20  ear $year month 
29a0: 24 6d 6f 6e 74 68 20 64 61 79 4f 66 4d 6f 6e 74  $month dayOfMont
29b0: 68 20 24 64 61 79 4f 66 4d 6f 6e 74 68 5d 20 32  h $dayOfMonth] 2
29c0: 33 36 31 32 32 32 5d 0a 20 20 20 20 73 77 69 74  361222].    swit
29d0: 63 68 20 2d 65 78 61 63 74 20 2d 2d 20 24 72 65  ch -exact -- $re
29e0: 6c 61 74 69 6f 6e 20 7b 0a 09 3c 3d 20 7b 0a 09  lation {..<= {..
29f0: 20 20 20 20 72 65 74 75 72 6e 20 5b 3a 3a 74 63      return [::tc
2a00: 6c 3a 3a 63 6c 6f 63 6b 3a 3a 57 65 65 6b 64 61  l::clock::Weekda
2a10: 79 4f 6e 4f 72 42 65 66 6f 72 65 20 24 64 61 79  yOnOrBefore $day
2a20: 4f 66 57 65 65 6b 20 5c 0a 09 09 20 20 20 20 5b  OfWeek \...    [
2a30: 64 69 63 74 20 67 65 74 20 24 64 61 74 65 20 6a  dict get $date j
2a40: 75 6c 69 61 6e 44 61 79 5d 5d 0a 09 7d 0a 09 3e  ulianDay]]..}..>
2a50: 3d 20 7b 0a 09 20 20 20 20 72 65 74 75 72 6e 20  = {..    return 
2a60: 5b 3a 3a 74 63 6c 3a 3a 63 6c 6f 63 6b 3a 3a 57  [::tcl::clock::W
2a70: 65 65 6b 64 61 79 4f 6e 4f 72 42 65 66 6f 72 65  eekdayOnOrBefore
2a80: 20 24 64 61 79 4f 66 57 65 65 6b 20 5c 0a 09 09   $dayOfWeek \...
2a90: 20 20 20 20 5b 65 78 70 72 20 7b 5b 64 69 63 74      [expr {[dict
2aa0: 20 67 65 74 20 24 64 61 74 65 20 6a 75 6c 69 61   get $date julia
2ab0: 6e 44 61 79 5d 20 2b 20 36 7d 5d 5d 0a 09 7d 0a  nDay] + 6}]]..}.
2ac0: 20 20 20 20 7d 0a 7d 0a 0a 23 2d 2d 2d 2d 2d 2d      }.}..#------
2ad0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2ae0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2af0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2b00: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2b10: 0a 23 0a 23 20 6f 6e 4c 61 73 74 57 65 65 6b 64  .#.# onLastWeekd
2b20: 61 79 49 6e 4d 6f 6e 74 68 20 2d 2d 0a 23 0a 23  ayInMonth --.#.#
2b30: 09 46 69 6e 64 20 74 68 65 20 6c 61 73 74 20 69  .Find the last i
2b40: 6e 73 74 61 6e 63 65 20 6f 66 20 61 20 67 69 76  nstance of a giv
2b50: 65 6e 20 77 65 65 6b 64 61 79 20 69 6e 20 61 20  en weekday in a 
2b60: 6d 6f 6e 74 68 2e 0a 23 0a 23 20 50 61 72 61 6d  month..#.# Param
2b70: 65 74 65 72 73 3a 0a 23 09 64 61 79 4f 66 57 65  eters:.#.dayOfWe
2b80: 65 6b 20 2d 20 57 65 65 6b 64 61 79 20 74 6f 20  ek - Weekday to 
2b90: 66 69 6e 64 20 28 4d 6f 6e 64 61 79 3d 31 2c 20  find (Monday=1, 
2ba0: 53 75 6e 64 61 79 3d 37 29 0a 23 09 79 65 61 72  Sunday=7).#.year
2bb0: 20 2d 20 47 72 65 67 6f 72 69 61 6e 20 79 65 61   - Gregorian yea
2bc0: 72 0a 23 09 6d 6f 6e 74 68 20 2d 20 4d 6f 6e 74  r.#.month - Mont
2bd0: 68 20 28 31 2d 31 32 29 0a 23 0a 23 20 52 65 73  h (1-12).#.# Res
2be0: 75 6c 74 73 3a 0a 23 09 52 65 74 75 72 6e 73 20  ults:.#.Returns 
2bf0: 74 68 65 20 4a 75 6c 69 61 6e 20 44 61 79 20 6e  the Julian Day n
2c00: 75 6d 62 65 72 20 6f 66 20 74 68 65 20 6c 61 73  umber of the las
2c10: 74 20 69 6e 73 74 61 6e 63 65 20 6f 66 0a 23 09  t instance of.#.
2c20: 74 68 65 20 67 69 76 65 6e 20 77 65 65 6b 64 61  the given weekda
2c30: 79 20 69 6e 20 74 68 65 20 67 69 76 65 6e 20 6d  y in the given m
2c40: 6f 6e 74 68 0a 23 0a 23 20 53 69 64 65 20 65 66  onth.#.# Side ef
2c50: 66 65 63 74 73 3a 0a 23 09 4e 6f 6e 65 2e 0a 23  fects:.#.None..#
2c60: 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  .#--------------
2c70: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2c80: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2c90: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2ca0: 2d 2d 2d 2d 2d 2d 2d 2d 0a 0a 70 72 6f 63 20 6f  --------..proc o
2cb0: 6e 4c 61 73 74 57 65 65 6b 64 61 79 49 6e 4d 6f  nLastWeekdayInMo
2cc0: 6e 74 68 20 7b 64 61 79 4f 66 57 65 65 6b 20 79  nth {dayOfWeek y
2cd0: 65 61 72 20 6d 6f 6e 74 68 7d 20 7b 0a 20 20 20  ear month} {.   
2ce0: 20 69 6e 63 72 20 6d 6f 6e 74 68 0a 20 20 20 20   incr month.    
2cf0: 23 20 46 69 6e 64 20 64 61 79 20 30 20 6f 66 20  # Find day 0 of 
2d00: 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 6d 6f  the following mo
2d10: 6e 74 68 2c 20 77 68 69 63 68 20 69 73 20 74 68  nth, which is th
2d20: 65 20 6c 61 73 74 20 64 61 79 20 6f 66 0a 20 20  e last day of.  
2d30: 20 20 23 20 74 68 65 20 63 75 72 72 65 6e 74 20    # the current 
2d40: 6d 6f 6e 74 68 2e 20 20 59 65 73 2c 20 69 74 20  month.  Yes, it 
2d50: 77 6f 72 6b 73 20 74 6f 20 61 73 6b 20 66 6f 72  works to ask for
2d60: 20 64 61 79 20 30 20 6f 66 20 6d 6f 6e 74 68 20   day 0 of month 
2d70: 31 33 21 0a 20 20 20 20 73 65 74 20 64 61 74 65  13!.    set date
2d80: 20 5b 3a 3a 74 63 6c 3a 3a 63 6c 6f 63 6b 3a 3a   [::tcl::clock::
2d90: 47 65 74 4a 75 6c 69 61 6e 44 61 79 46 72 6f 6d  GetJulianDayFrom
2da0: 45 72 61 59 65 61 72 4d 6f 6e 74 68 44 61 79 20  EraYearMonthDay 
2db0: 5b 64 69 63 74 20 63 72 65 61 74 65 20 5c 0a 09  [dict create \..
2dc0: 20 20 20 20 65 72 61 20 43 45 20 79 65 61 72 20      era CE year 
2dd0: 24 79 65 61 72 20 6d 6f 6e 74 68 20 24 6d 6f 6e  $year month $mon
2de0: 74 68 20 64 61 79 4f 66 4d 6f 6e 74 68 20 30 5d  th dayOfMonth 0]
2df0: 20 32 33 36 31 32 32 32 5d 0a 20 20 20 20 72 65   2361222].    re
2e00: 74 75 72 6e 20 5b 3a 3a 74 63 6c 3a 3a 63 6c 6f  turn [::tcl::clo
2e10: 63 6b 3a 3a 57 65 65 6b 64 61 79 4f 6e 4f 72 42  ck::WeekdayOnOrB
2e20: 65 66 6f 72 65 20 24 64 61 79 4f 66 57 65 65 6b  efore $dayOfWeek
2e30: 20 5c 0a 09 20 20 20 20 5b 64 69 63 74 20 67 65   \..    [dict ge
2e40: 74 20 24 64 61 74 65 20 6a 75 6c 69 61 6e 44 61  t $date julianDa
2e50: 79 5d 5d 0a 7d 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d  y]].}..#--------
2e60: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2e70: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2e80: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2e90: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23  --------------.#
2ea0: 0a 23 20 70 61 72 73 65 54 4f 44 20 2d 2d 0a 23  .# parseTOD --.#
2eb0: 0a 23 09 50 61 72 73 65 73 20 74 68 65 20 73 70  .#.Parses the sp
2ec0: 65 63 69 66 69 63 61 74 69 6f 6e 20 6f 66 20 61  ecification of a
2ed0: 20 74 69 6d 65 20 6f 66 20 64 61 79 20 69 6e 20   time of day in 
2ee0: 61 6e 20 4f 6c 73 6f 6e 20 66 69 6c 65 2e 0a 23  an Olson file..#
2ef0: 0a 23 20 50 61 72 61 6d 65 74 65 72 73 3a 0a 23  .# Parameters:.#
2f00: 09 74 6f 64 20 2d 20 54 69 6d 65 20 6f 66 20 64  .tod - Time of d
2f10: 61 79 2c 20 77 68 69 63 68 20 6d 61 79 20 62 65  ay, which may be
2f20: 20 66 6f 6c 6c 6f 77 65 64 20 62 79 20 27 77 27   followed by 'w'
2f30: 2c 20 27 73 27 2c 20 27 75 27 2c 20 27 67 27 0a  , 's', 'u', 'g'.
2f40: 23 09 20 20 20 20 20 20 6f 72 20 27 7a 27 2e 20  #.      or 'z'. 
2f50: 20 27 77 27 20 28 6f 72 20 6e 6f 20 6c 65 74 74   'w' (or no lett
2f60: 65 72 29 20 64 65 73 69 67 6e 61 74 65 73 20 61  er) designates a
2f70: 20 77 61 6c 6c 20 63 6c 6f 63 6b 20 74 69 6d 65   wall clock time
2f80: 2c 0a 23 09 20 20 20 20 20 20 27 73 27 20 64 65  ,.#.      's' de
2f90: 73 69 67 6e 61 74 65 73 20 53 74 61 6e 64 61 72  signates Standar
2fa0: 64 20 54 69 6d 65 20 69 6e 20 74 68 65 20 67 69  d Time in the gi
2fb0: 76 65 6e 20 7a 6f 6e 65 2c 20 61 6e 64 0a 23 09  ven zone, and.#.
2fc0: 20 20 20 20 20 20 27 75 27 2c 20 27 67 27 2c 20        'u', 'g', 
2fd0: 61 6e 64 20 27 7a 27 20 61 6c 6c 20 64 65 73 69  and 'z' all desi
2fe0: 67 6e 61 74 65 20 55 54 43 2e 0a 23 0a 23 20 52  gnate UTC..#.# R
2ff0: 65 73 75 6c 74 73 3a 0a 23 09 52 65 74 75 72 6e  esults:.#.Return
3000: 73 20 61 20 74 77 6f 20 65 6c 65 6d 65 6e 74 20  s a two element 
3010: 6c 69 73 74 20 63 6f 6e 74 61 69 6e 69 6e 67 20  list containing 
3020: 61 20 63 6f 75 6e 74 20 6f 66 20 73 65 63 6f 6e  a count of secon
3030: 64 73 20 66 72 6f 6d 0a 23 09 6d 69 64 6e 69 67  ds from.#.midnig
3040: 68 74 20 61 6e 64 20 74 68 65 20 6c 65 74 74 65  ht and the lette
3050: 72 20 74 68 61 74 20 66 6f 6c 6c 6f 77 65 64 20  r that followed 
3060: 74 68 65 20 74 69 6d 65 2e 0a 23 0a 23 20 53 69  the time..#.# Si
3070: 64 65 20 65 66 66 65 63 74 73 3a 0a 23 09 52 65  de effects:.#.Re
3080: 70 6f 72 74 73 20 61 6e 64 20 63 6f 75 6e 74 73  ports and counts
3090: 20 61 6e 20 65 72 72 6f 72 20 69 66 20 74 68 65   an error if the
30a0: 20 74 69 6d 65 20 63 61 6e 6e 6f 74 20 62 65 20   time cannot be 
30b0: 70 61 72 73 65 64 2e 0a 23 0a 23 2d 2d 2d 2d 2d  parsed..#.#-----
30c0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
30d0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
30e0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
30f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3100: 2d 0a 0a 70 72 6f 63 20 70 61 72 73 65 54 4f 44  -..proc parseTOD
3110: 20 7b 74 6f 64 7d 20 7b 0a 20 20 20 20 69 66 20   {tod} {.    if 
3120: 7b 21 5b 72 65 67 65 78 70 20 2d 65 78 70 61 6e  {![regexp -expan
3130: 64 65 64 20 7b 0a 09 5e 0a 09 28 5b 5b 3a 64 69  ded {..^..([[:di
3140: 67 69 74 3a 5d 5d 7b 31 2c 32 7d 29 09 09 23 20  git:]]{1,2})..# 
3150: 66 69 65 6c 64 20 31 20 2d 20 68 6f 75 72 0a 09  field 1 - hour..
3160: 28 3f 3a 0a 09 20 20 20 20 3a 28 5b 5b 3a 64 69  (?:..    :([[:di
3170: 67 69 74 3a 5d 5d 7b 32 7d 29 09 09 23 20 66 69  git:]]{2})..# fi
3180: 65 6c 64 20 32 20 2d 20 6d 69 6e 75 74 65 0a 09  eld 2 - minute..
3190: 20 20 20 20 28 3f 3a 0a 09 09 3a 28 5b 5b 3a 64      (?:...:([[:d
31a0: 69 67 69 74 3a 5d 5d 7b 32 7d 29 09 23 20 66 69  igit:]]{2}).# fi
31b0: 65 6c 64 20 33 20 2d 20 73 65 63 6f 6e 64 0a 09  eld 3 - second..
31c0: 20 20 20 20 29 3f 0a 09 29 3f 0a 09 28 3f 3a 0a      )?..)?..(?:.
31d0: 09 20 20 20 20 28 5b 77 73 75 67 7a 5d 29 09 09  .    ([wsugz])..
31e0: 09 23 20 66 69 65 6c 64 20 34 20 2d 20 74 79 70  .# field 4 - typ
31f0: 65 20 69 6e 64 69 63 61 74 6f 72 0a 09 29 3f 0a  e indicator..)?.
3200: 20 20 20 20 7d 20 24 74 6f 64 20 2d 3e 20 68 6f      } $tod -> ho
3210: 75 72 20 6d 69 6e 75 74 65 20 73 65 63 6f 6e 64  ur minute second
3220: 20 69 6e 64 5d 7d 20 7b 0a 09 70 75 74 73 20 73   ind]} {..puts s
3230: 74 64 65 72 72 20 22 24 66 69 6c 65 4e 61 6d 65  tderr "$fileName
3240: 3a 24 6c 6e 6f 3a 63 61 6e 27 74 20 70 61 72 73  :$lno:can't pars
3250: 65 20 74 69 6d 65 20 66 69 65 6c 64 20 5c 22 24  e time field \"$
3260: 74 6f 64 5c 22 22 0a 09 69 6e 63 72 20 65 72 72  tod\""..incr err
3270: 6f 72 43 6f 75 6e 74 0a 20 20 20 20 7d 0a 20 20  orCount.    }.  
3280: 20 20 73 63 61 6e 20 24 68 6f 75 72 20 25 64 20    scan $hour %d 
3290: 68 6f 75 72 0a 20 20 20 20 69 66 20 7b 24 6d 69  hour.    if {$mi
32a0: 6e 75 74 65 20 6e 65 20 22 22 7d 20 7b 0a 09 73  nute ne ""} {..s
32b0: 63 61 6e 20 24 6d 69 6e 75 74 65 20 25 64 20 6d  can $minute %d m
32c0: 69 6e 75 74 65 0a 20 20 20 20 7d 20 65 6c 73 65  inute.    } else
32d0: 20 7b 0a 09 73 65 74 20 6d 69 6e 75 74 65 20 30   {..set minute 0
32e0: 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 20 7b 24  .    }.    if {$
32f0: 73 65 63 6f 6e 64 20 6e 65 20 22 22 7d 20 7b 0a  second ne ""} {.
3300: 09 73 63 61 6e 20 24 73 65 63 6f 6e 64 20 25 64  .scan $second %d
3310: 20 73 65 63 6f 6e 64 0a 20 20 20 20 7d 20 65 6c   second.    } el
3320: 73 65 20 7b 0a 09 73 65 74 20 73 65 63 6f 6e 64  se {..set second
3330: 20 30 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 20   0.    }.    if 
3340: 7b 24 69 6e 64 20 65 71 20 22 22 7d 20 7b 0a 09  {$ind eq ""} {..
3350: 73 65 74 20 69 6e 64 20 77 0a 20 20 20 20 7d 0a  set ind w.    }.
3360: 20 20 20 20 72 65 74 75 72 6e 20 5b 6c 69 73 74      return [list
3370: 20 5b 65 78 70 72 20 7b 28 24 68 6f 75 72 20 2a   [expr {($hour *
3380: 20 36 30 20 2b 20 24 6d 69 6e 75 74 65 29 20 2a   60 + $minute) *
3390: 20 36 30 20 2b 20 24 73 65 63 6f 6e 64 7d 5d 20   60 + $second}] 
33a0: 24 69 6e 64 5d 0a 7d 0a 0a 23 2d 2d 2d 2d 2d 2d  $ind].}..#------
33b0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
33c0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
33d0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
33e0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
33f0: 0a 23 0a 23 20 70 61 72 73 65 4f 66 66 73 65 74  .#.# parseOffset
3400: 54 69 6d 65 20 2d 2d 0a 23 0a 23 09 50 61 72 73  Time --.#.#.Pars
3410: 65 73 20 74 68 65 20 73 70 65 63 69 66 69 63 61  es the specifica
3420: 74 69 6f 6e 20 6f 66 20 61 6e 20 6f 66 66 73 65  tion of an offse
3430: 74 20 74 69 6d 65 20 69 6e 20 61 6e 20 4f 6c 73  t time in an Ols
3440: 6f 6e 20 66 69 6c 65 2e 0a 23 0a 23 20 50 61 72  on file..#.# Par
3450: 61 6d 65 74 65 72 73 3a 0a 23 09 6f 66 66 73 65  ameters:.#.offse
3460: 74 20 2d 20 4f 66 66 73 65 74 20 74 69 6d 65 20  t - Offset time 
3470: 61 73 20 5b 2b 2d 5d 68 68 3a 6d 6d 3a 73 73 0a  as [+-]hh:mm:ss.
3480: 23 0a 23 20 52 65 73 75 6c 74 73 3a 0a 23 09 52  #.# Results:.#.R
3490: 65 74 75 72 6e 73 20 74 68 65 20 6f 66 66 73 65  eturns the offse
34a0: 74 20 74 69 6d 65 20 61 73 20 61 20 63 6f 75 6e  t time as a coun
34b0: 74 20 6f 66 20 73 65 63 6f 6e 64 73 2e 0a 23 0a  t of seconds..#.
34c0: 23 20 53 69 64 65 20 65 66 66 65 63 74 73 3a 0a  # Side effects:.
34d0: 23 09 52 65 70 6f 72 74 73 20 61 6e 64 20 63 6f  #.Reports and co
34e0: 75 6e 74 73 20 61 6e 20 65 72 72 6f 72 20 69 66  unts an error if
34f0: 20 74 68 65 20 74 69 6d 65 20 63 61 6e 6e 6f 74   the time cannot
3500: 20 62 65 20 70 61 72 73 65 64 2e 0a 23 0a 23 2d   be parsed..#.#-
3510: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3520: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3530: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3540: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3550: 2d 2d 2d 2d 2d 0a 0a 70 72 6f 63 20 70 61 72 73  -----..proc pars
3560: 65 4f 66 66 73 65 74 54 69 6d 65 20 7b 6f 66 66  eOffsetTime {off
3570: 73 65 74 7d 20 7b 0a 20 20 20 20 69 66 20 7b 21  set} {.    if {!
3580: 5b 72 65 67 65 78 70 20 2d 65 78 70 61 6e 64 65  [regexp -expande
3590: 64 20 7b 0a 09 5e 0a 09 28 5b 2d 2b 5d 29 3f 09  d {..^..([-+])?.
35a0: 09 09 09 23 20 66 69 65 6c 64 20 31 20 2d 20 73  ...# field 1 - s
35b0: 69 67 6e 75 6d 0a 09 28 5b 5b 3a 64 69 67 69 74  ignum..([[:digit
35c0: 3a 5d 5d 7b 31 2c 32 7d 29 09 09 23 20 66 69 65  :]]{1,2})..# fie
35d0: 6c 64 20 32 20 2d 20 68 6f 75 72 0a 09 28 3f 3a  ld 2 - hour..(?:
35e0: 0a 09 20 20 20 20 3a 28 5b 5b 3a 64 69 67 69 74  ..    :([[:digit
35f0: 3a 5d 5d 7b 32 7d 29 09 09 23 20 66 69 65 6c 64  :]]{2})..# field
3600: 20 33 20 2d 20 6d 69 6e 75 74 65 0a 09 20 20 20   3 - minute..   
3610: 20 28 3f 3a 0a 09 09 3a 28 5b 5b 3a 64 69 67 69   (?:...:([[:digi
3620: 74 3a 5d 5d 7b 32 7d 29 09 23 20 66 69 65 6c 64  t:]]{2}).# field
3630: 20 34 20 2d 20 73 65 63 6f 6e 64 0a 09 20 20 20   4 - second..   
3640: 20 29 3f 0a 09 29 3f 0a 20 20 20 20 7d 20 24 6f   )?..)?.    } $o
3650: 66 66 73 65 74 20 2d 3e 20 73 69 67 6e 75 6d 20  ffset -> signum 
3660: 68 6f 75 72 20 6d 69 6e 75 74 65 20 73 65 63 6f  hour minute seco
3670: 6e 64 5d 7d 20 7b 0a 09 70 75 74 73 20 73 74 64  nd]} {..puts std
3680: 65 72 72 20 22 24 66 69 6c 65 4e 61 6d 65 3a 24  err "$fileName:$
3690: 6c 6e 6f 3a 63 61 6e 27 74 20 70 61 72 73 65 20  lno:can't parse 
36a0: 6f 66 66 73 65 74 20 74 69 6d 65 20 5c 22 24 6f  offset time \"$o
36b0: 66 66 73 65 74 5c 22 22 0a 09 69 6e 63 72 20 65  ffset\""..incr e
36c0: 72 72 6f 72 43 6f 75 6e 74 0a 20 20 20 20 7d 0a  rrorCount.    }.
36d0: 20 20 20 20 61 70 70 65 6e 64 20 73 69 67 6e 75      append signu
36e0: 6d 20 31 0a 20 20 20 20 73 63 61 6e 20 24 68 6f  m 1.    scan $ho
36f0: 75 72 20 25 64 20 68 6f 75 72 0a 20 20 20 20 69  ur %d hour.    i
3700: 66 20 7b 24 6d 69 6e 75 74 65 20 6e 65 20 22 22  f {$minute ne ""
3710: 7d 20 7b 0a 09 73 63 61 6e 20 24 6d 69 6e 75 74  } {..scan $minut
3720: 65 20 25 64 20 6d 69 6e 75 74 65 0a 20 20 20 20  e %d minute.    
3730: 7d 20 65 6c 73 65 20 7b 0a 09 73 65 74 20 6d 69  } else {..set mi
3740: 6e 75 74 65 20 30 0a 20 20 20 20 7d 0a 20 20 20  nute 0.    }.   
3750: 20 69 66 20 7b 24 73 65 63 6f 6e 64 20 6e 65 20   if {$second ne 
3760: 22 22 7d 20 7b 0a 09 73 63 61 6e 20 24 73 65 63  ""} {..scan $sec
3770: 6f 6e 64 20 25 64 20 73 65 63 6f 6e 64 0a 20 20  ond %d second.  
3780: 20 20 7d 20 65 6c 73 65 20 7b 0a 09 73 65 74 20    } else {..set 
3790: 73 65 63 6f 6e 64 20 30 0a 20 20 20 20 7d 0a 20  second 0.    }. 
37a0: 20 20 20 72 65 74 75 72 6e 20 5b 65 78 70 72 20     return [expr 
37b0: 7b 28 28 24 68 6f 75 72 20 2a 20 36 30 20 2b 20  {(($hour * 60 + 
37c0: 24 6d 69 6e 75 74 65 29 20 2a 20 36 30 20 2b 20  $minute) * 60 + 
37d0: 24 73 65 63 6f 6e 64 29 20 2a 20 24 73 69 67 6e  $second) * $sign
37e0: 75 6d 7d 5d 0a 0a 7d 0a 0a 23 2d 2d 2d 2d 2d 2d  um}]..}..#------
37f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3800: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3810: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3820: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3830: 0a 23 0a 23 20 6c 6f 6f 6b 75 70 4d 6f 6e 74 68  .#.# lookupMonth
3840: 20 2d 0a 23 09 4c 6f 6f 6b 73 20 75 70 20 61 20   -.#.Looks up a 
3850: 6d 6f 6e 74 68 20 62 79 20 6e 61 6d 65 0a 23 0a  month by name.#.
3860: 23 20 50 61 72 61 6d 65 74 65 72 73 3a 0a 23 09  # Parameters:.#.
3870: 6d 6f 6e 74 68 20 2d 20 4e 61 6d 65 20 6f 66 20  month - Name of 
3880: 61 20 6d 6f 6e 74 68 2e 0a 23 0a 23 20 52 65 73  a month..#.# Res
3890: 75 6c 74 73 3a 0a 23 09 52 65 74 75 72 6e 73 20  ults:.#.Returns 
38a0: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 74 68  the number of th
38b0: 65 20 6d 6f 6e 74 68 2e 0a 23 0a 23 20 53 69 64  e month..#.# Sid
38c0: 65 20 65 66 66 65 63 74 73 3a 0a 23 09 4e 6f 6e  e effects:.#.Non
38d0: 65 2e 0a 23 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  e..#.#----------
38e0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
38f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3900: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3910: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 0a 70 72  ------------..pr
3920: 6f 63 20 6c 6f 6f 6b 75 70 4d 6f 6e 74 68 20 7b  oc lookupMonth {
3930: 6d 6f 6e 74 68 7d 20 7b 0a 20 20 20 20 73 65 74  month} {.    set
3940: 20 69 6e 64 78 20 5b 6c 73 65 61 72 63 68 20 2d   indx [lsearch -
3950: 72 65 67 65 78 70 20 7b 0a 09 7b 7d 20 4a 61 6e  regexp {..{} Jan
3960: 75 61 72 79 20 46 65 62 72 75 61 72 79 20 4d 61  uary February Ma
3970: 72 63 68 20 41 70 72 69 6c 20 4d 61 79 20 4a 75  rch April May Ju
3980: 6e 65 0a 09 4a 75 6c 79 20 41 75 67 75 73 74 20  ne..July August 
3990: 53 65 70 74 65 6d 62 65 72 20 4f 63 74 6f 62 65  September Octobe
39a0: 72 20 4e 6f 76 65 6d 62 65 72 20 44 65 63 65 6d  r November Decem
39b0: 62 65 72 0a 20 20 20 20 7d 20 24 7b 6d 6f 6e 74  ber.    } ${mont
39c0: 68 7d 2e 2a 5d 0a 20 20 20 20 69 66 20 7b 24 69  h}.*].    if {$i
39d0: 6e 64 78 20 3c 20 31 7d 20 7b 0a 09 65 72 72 6f  ndx < 1} {..erro
39e0: 72 20 22 75 6e 6b 6e 6f 77 6e 20 6d 6f 6e 74 68  r "unknown month
39f0: 20 6e 61 6d 65 20 5c 22 24 6d 6f 6e 74 68 5c 22   name \"$month\"
3a00: 22 0a 20 20 20 20 7d 0a 20 20 20 20 72 65 74 75  ".    }.    retu
3a10: 72 6e 20 24 69 6e 64 78 0a 7d 0a 0a 23 2d 2d 2d  rn $indx.}..#---
3a20: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3a30: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3a40: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3a50: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3a60: 2d 2d 2d 0a 23 0a 23 20 6c 6f 6f 6b 75 70 44 61  ---.#.# lookupDa
3a70: 79 4f 66 57 65 65 6b 20 2d 2d 0a 23 0a 23 09 4c  yOfWeek --.#.#.L
3a80: 6f 6f 6b 73 20 75 70 20 74 68 65 20 6e 61 6d 65  ooks up the name
3a90: 20 6f 66 20 61 20 77 65 65 6b 64 61 79 2e 0a 23   of a weekday..#
3aa0: 0a 23 20 50 61 72 61 6d 65 74 65 72 73 3a 0a 23  .# Parameters:.#
3ab0: 09 77 64 61 79 20 2d 20 57 65 65 6b 64 61 79 20  .wday - Weekday 
3ac0: 6e 61 6d 65 20 28 6f 72 20 61 20 75 6e 69 71 75  name (or a uniqu
3ad0: 65 20 70 72 65 66 69 78 29 2e 0a 23 0a 23 20 52  e prefix)..#.# R
3ae0: 65 73 75 6c 74 73 3a 0a 23 09 52 65 74 75 72 6e  esults:.#.Return
3af0: 73 20 74 68 65 20 77 65 65 6b 64 61 79 20 6e 75  s the weekday nu
3b00: 6d 62 65 72 20 28 4d 6f 6e 64 61 79 3d 31 2c 20  mber (Monday=1, 
3b10: 53 75 6e 64 61 79 3d 37 29 0a 23 0a 23 20 53 69  Sunday=7).#.# Si
3b20: 64 65 20 65 66 66 65 63 74 73 3a 0a 23 09 4e 6f  de effects:.#.No
3b30: 6e 65 2e 0a 23 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d  ne..#.#---------
3b40: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3b50: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3b60: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3b70: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 0a 70  -------------..p
3b80: 72 6f 63 20 6c 6f 6f 6b 75 70 44 61 79 4f 66 57  roc lookupDayOfW
3b90: 65 65 6b 20 7b 77 64 61 79 7d 20 7b 0a 20 20 20  eek {wday} {.   
3ba0: 20 73 65 74 20 69 6e 64 78 20 5b 6c 73 65 61 72   set indx [lsear
3bb0: 63 68 20 2d 72 65 67 65 78 70 20 7b 0a 09 7b 7d  ch -regexp {..{}
3bc0: 20 4d 6f 6e 64 61 79 20 54 75 65 73 64 61 79 20   Monday Tuesday 
3bd0: 57 65 64 6e 65 73 64 61 79 20 54 68 75 72 73 64  Wednesday Thursd
3be0: 61 79 20 46 72 69 64 61 79 20 53 61 74 75 72 64  ay Friday Saturd
3bf0: 61 79 20 53 75 6e 64 61 79 0a 20 20 20 20 7d 20  ay Sunday.    } 
3c00: 24 7b 77 64 61 79 7d 2e 2a 5d 0a 20 20 20 20 69  ${wday}.*].    i
3c10: 66 20 7b 24 69 6e 64 78 20 3c 20 31 7d 20 7b 0a  f {$indx < 1} {.
3c20: 09 65 72 72 6f 72 20 22 75 6e 6b 6e 6f 77 6e 20  .error "unknown 
3c30: 77 65 65 6b 64 61 79 20 6e 61 6d 65 20 5c 22 24  weekday name \"$
3c40: 77 64 61 79 5c 22 22 0a 20 20 20 20 7d 0a 20 20  wday\"".    }.  
3c50: 20 20 72 65 74 75 72 6e 20 24 69 6e 64 78 0a 7d    return $indx.}
3c60: 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ..#-------------
3c70: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3c80: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3c90: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3ca0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 0a 23 20 70 61  ---------.#.# pa
3cb0: 72 73 65 5a 6f 6e 65 20 2d 2d 0a 23 0a 23 09 50  rseZone --.#.#.P
3cc0: 61 72 73 65 73 20 61 20 5a 6f 6e 65 20 64 69 72  arses a Zone dir
3cd0: 65 63 74 69 76 65 20 69 6e 20 61 6e 20 4f 6c 73  ective in an Ols
3ce0: 6f 6e 20 66 69 6c 65 0a 23 0a 23 20 50 61 72 61  on file.#.# Para
3cf0: 6d 65 74 65 72 73 3a 0a 23 09 66 69 6c 65 4e 61  meters:.#.fileNa
3d00: 6d 65 20 2d 2d 20 4e 61 6d 65 20 6f 66 20 74 68  me -- Name of th
3d10: 65 20 66 69 6c 65 20 62 65 69 6e 67 20 70 61 72  e file being par
3d20: 73 65 64 2e 0a 23 09 6c 6e 6f 20 2d 2d 20 4c 69  sed..#.lno -- Li
3d30: 6e 65 20 6e 75 6d 62 65 72 20 77 69 74 68 69 6e  ne number within
3d40: 20 74 68 65 20 66 69 6c 65 2e 0a 23 09 7a 6f 6e   the file..#.zon
3d50: 65 20 2d 2d 20 4e 61 6d 65 20 6f 66 20 74 68 65  e -- Name of the
3d60: 20 74 69 6d 65 20 7a 6f 6e 65 0a 23 09 77 6f 72   time zone.#.wor
3d70: 64 73 20 2d 2d 20 52 65 6d 61 69 6e 69 6e 67 20  ds -- Remaining 
3d80: 77 6f 72 64 73 20 6f 6e 20 74 68 65 20 6c 69 6e  words on the lin
3d90: 65 2e 0a 23 09 73 74 61 72 74 20 2d 2d 20 27 55  e..#.start -- 'U
3da0: 6e 74 69 6c 27 20 74 69 6d 65 20 66 72 6f 6d 20  ntil' time from 
3db0: 74 68 65 20 70 72 65 76 69 6f 75 73 20 6c 69 6e  the previous lin
3dc0: 65 20 69 66 20 74 68 69 73 20 69 73 20 61 0a 23  e if this is a.#
3dd0: 09 09 20 63 6f 6e 74 69 6e 75 61 74 69 6f 6e 20  .. continuation 
3de0: 6c 69 6e 65 2c 20 6f 72 20 27 6d 69 6e 69 6d 75  line, or 'minimu
3df0: 6d 27 20 69 66 20 74 68 69 73 20 69 73 20 74 68  m' if this is th
3e00: 65 20 66 69 72 73 74 20 6c 69 6e 65 2e 0a 23 0a  e first line..#.
3e10: 23 20 52 65 73 75 6c 74 73 3a 0a 23 09 52 65 74  # Results:.#.Ret
3e20: 75 72 6e 73 20 74 68 65 20 27 75 6e 74 69 6c 27  urns the 'until'
3e30: 20 66 69 65 6c 64 20 6f 66 20 74 68 65 20 63 75   field of the cu
3e40: 72 72 65 6e 74 20 6c 69 6e 65 0a 23 0a 23 20 53  rrent line.#.# S
3e50: 69 64 65 20 65 66 66 65 63 74 73 3a 0a 23 09 53  ide effects:.#.S
3e60: 74 6f 72 65 73 20 61 20 72 6f 77 20 69 6e 20 74  tores a row in t
3e70: 68 65 20 27 7a 6f 6e 65 73 27 20 61 72 72 61 79  he 'zones' array
3e80: 20 64 65 73 63 72 69 62 69 6e 67 20 74 68 65 20   describing the 
3e90: 63 75 72 72 65 6e 74 20 7a 6f 6e 65 2e 0a 23 09  current zone..#.
3ea0: 54 68 65 20 72 6f 77 20 63 6f 6e 73 69 73 74 73  The row consists
3eb0: 20 6f 66 20 61 20 73 74 61 72 74 20 74 69 6d 65   of a start time
3ec0: 20 28 79 65 61 72 20 6d 6f 6e 74 68 20 64 61 79   (year month day
3ed0: 20 74 6f 64 29 2c 20 61 20 53 74 61 6e 64 61 72   tod), a Standar
3ee0: 64 0a 23 09 54 69 6d 65 20 6f 66 66 73 65 74 20  d.#.Time offset 
3ef0: 66 72 6f 6d 20 47 72 65 65 6e 77 69 63 68 2c 20  from Greenwich, 
3f00: 61 20 44 61 79 6c 69 67 68 74 20 53 61 76 69 6e  a Daylight Savin
3f10: 67 20 54 69 6d 65 20 6f 66 66 73 65 74 20 66 72  g Time offset fr
3f20: 6f 6d 0a 23 09 53 74 61 6e 64 61 72 64 20 54 69  om.#.Standard Ti
3f30: 6d 65 2c 20 61 6e 64 20 61 20 66 6f 72 6d 61 74  me, and a format
3f40: 20 66 6f 72 20 70 72 69 6e 74 69 6e 67 20 74 68   for printing th
3f50: 65 20 74 69 6d 65 20 7a 6f 6e 65 2e 0a 23 0a 23  e time zone..#.#
3f60: 09 54 68 65 20 73 74 61 72 74 20 74 69 6d 65 20  .The start time 
3f70: 69 73 20 74 68 65 20 72 65 73 75 6c 74 20 6f 66  is the result of
3f80: 20 61 6e 20 65 61 72 6c 69 65 72 20 63 61 6c 6c   an earlier call
3f90: 20 74 6f 20 27 70 61 72 73 65 55 6e 74 69 6c 27   to 'parseUntil'
3fa0: 0a 23 09 6f 72 20 65 6c 73 65 20 74 68 65 20 6b  .#.or else the k
3fb0: 65 79 77 6f 72 64 20 27 6d 69 6e 69 6d 75 6d 27  eyword 'minimum'
3fc0: 2e 09 54 68 65 20 47 4d 54 20 6f 66 66 73 65 74  ..The GMT offset
3fd0: 20 69 73 20 74 68 65 0a 23 09 72 65 73 75 6c 74   is the.#.result
3fe0: 20 6f 66 20 61 20 63 61 6c 6c 20 74 6f 20 27 70   of a call to 'p
3ff0: 61 72 73 65 4f 66 66 73 65 74 54 69 6d 65 27 2e  arseOffsetTime'.
4000: 09 54 68 65 20 44 61 79 6c 69 67 68 74 20 53 61  .The Daylight Sa
4010: 76 69 6e 67 0a 23 09 54 69 6d 65 20 6f 66 66 73  ving.#.Time offs
4020: 65 74 20 69 73 20 72 65 70 72 65 73 65 6e 74 65  et is represente
4030: 64 20 61 73 20 61 20 70 61 72 74 69 61 6c 20 54  d as a partial T
4040: 63 6c 20 63 6f 6d 6d 61 6e 64 2e 20 54 6f 20 74  cl command. To t
4050: 68 65 0a 23 09 63 6f 6d 6d 61 6e 64 20 77 69 6c  he.#.command wil
4060: 6c 20 62 65 20 61 70 70 65 6e 64 65 64 20 61 20  l be appended a 
4070: 73 74 61 72 74 20 74 69 6d 65 20 28 73 65 63 6f  start time (seco
4080: 6e 64 73 20 66 72 6f 6d 20 65 70 6f 63 68 29 0a  nds from epoch).
4090: 23 09 74 68 65 20 63 75 72 72 65 6e 74 20 6f 66  #.the current of
40a0: 66 73 65 74 20 6f 66 20 53 74 61 6e 64 61 72 64  fset of Standard
40b0: 20 54 69 6d 65 20 66 72 6f 6d 20 47 72 65 65 6e   Time from Green
40c0: 77 69 63 68 2c 20 74 68 65 20 63 75 72 72 65 6e  wich, the curren
40d0: 74 0a 23 09 6f 66 66 73 65 74 20 6f 66 20 44 61  t.#.offset of Da
40e0: 79 6c 69 67 68 74 20 53 61 76 69 6e 67 20 54 69  ylight Saving Ti
40f0: 6d 65 20 66 72 6f 6d 20 47 72 65 65 6e 77 69 63  me from Greenwic
4100: 68 2c 20 74 68 65 20 64 65 66 61 75 6c 74 0a 23  h, the default.#
4110: 09 6f 66 66 73 65 74 20 66 72 6f 6d 20 74 68 69  .offset from thi
4120: 73 20 6c 69 6e 65 2c 20 74 68 65 20 6e 61 6d 65  s line, the name
4130: 20 70 61 74 74 65 72 6e 20 66 72 6f 6d 20 74 68   pattern from th
4140: 69 73 20 6c 69 6e 65 2c 0a 23 09 74 68 65 20 27  is line,.#.the '
4150: 75 6e 74 69 6c 27 20 66 69 65 6c 64 20 66 72 6f  until' field fro
4160: 6d 20 74 68 69 73 20 6c 69 6e 65 2c 20 61 6e 64  m this line, and
4170: 20 61 20 76 61 72 69 61 62 6c 65 20 6e 61 6d 65   a variable name
4180: 20 77 68 65 72 65 20 70 6f 69 6e 74 73 0a 23 09   where points.#.
4190: 61 72 65 20 74 6f 20 62 65 20 73 74 6f 72 65 64  are to be stored
41a0: 2e 20 20 54 68 69 73 20 63 6f 6d 6d 61 6e 64 20  .  This command 
41b0: 69 73 20 69 6d 70 6c 65 6d 65 6e 74 65 64 20 62  is implemented b
41c0: 79 20 74 68 65 20 27 61 70 70 6c 79 4e 6f 52 75  y the 'applyNoRu
41d0: 6c 65 27 2c 0a 23 09 27 61 70 70 6c 79 44 53 54  le',.#.'applyDST
41e0: 4f 66 66 73 65 74 27 20 61 6e 64 20 27 61 70 70  Offset' and 'app
41f0: 6c 79 52 75 6c 65 73 27 20 70 72 6f 63 65 64 75  lyRules' procedu
4200: 72 65 73 2e 0a 23 0a 23 2d 2d 2d 2d 2d 2d 2d 2d  res..#.#--------
4210: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
4220: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
4230: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
4240: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 0a  --------------..
4250: 70 72 6f 63 20 70 61 72 73 65 5a 6f 6e 65 20 7b  proc parseZone {
4260: 66 69 6c 65 4e 61 6d 65 20 6c 6e 6f 20 7a 6f 6e  fileName lno zon
4270: 65 20 77 6f 72 64 73 20 73 74 61 72 74 7d 20 7b  e words start} {
4280: 0a 20 20 20 20 76 61 72 69 61 62 6c 65 20 7a 6f  .    variable zo
4290: 6e 65 73 0a 20 20 20 20 76 61 72 69 61 62 6c 65  nes.    variable
42a0: 20 72 75 6c 65 73 0a 20 20 20 20 76 61 72 69 61   rules.    varia
42b0: 62 6c 65 20 65 72 72 6f 72 43 6f 75 6e 74 0a 20  ble errorCount. 
42c0: 20 20 20 76 61 72 69 61 62 6c 65 20 66 6f 72 77     variable forw
42d0: 61 72 64 52 75 6c 65 52 65 66 73 0a 0a 20 20 20  ardRuleRefs..   
42e0: 20 6c 61 73 73 69 67 6e 20 24 77 6f 72 64 73 20   lassign $words 
42f0: 67 6d 74 6f 66 66 20 73 61 76 65 20 66 6f 72 6d  gmtoff save form
4300: 61 74 0a 20 20 20 20 69 66 20 7b 5b 63 61 74 63  at.    if {[catc
4310: 68 20 7b 70 61 72 73 65 4f 66 66 73 65 74 54 69  h {parseOffsetTi
4320: 6d 65 20 24 67 6d 74 6f 66 66 7d 20 67 6d 74 6f  me $gmtoff} gmto
4330: 66 66 5d 7d 20 7b 0a 09 70 75 74 73 20 73 74 64  ff]} {..puts std
4340: 65 72 72 20 22 24 66 69 6c 65 4e 61 6d 65 3a 24  err "$fileName:$
4350: 6c 6e 6f 3a 24 67 6d 74 6f 66 66 22 0a 09 69 6e  lno:$gmtoff"..in
4360: 63 72 20 65 72 72 6f 72 43 6f 75 6e 74 0a 09 72  cr errorCount..r
4370: 65 74 75 72 6e 0a 20 20 20 20 7d 0a 20 20 20 20  eturn.    }.    
4380: 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73  if {[info exists
4390: 20 72 75 6c 65 73 28 24 73 61 76 65 29 5d 7d 20   rules($save)]} 
43a0: 7b 0a 09 73 65 74 20 73 61 76 65 20 5b 6c 69 73  {..set save [lis
43b0: 74 20 61 70 70 6c 79 52 75 6c 65 73 20 24 73 61  t applyRules $sa
43c0: 76 65 5d 0a 20 20 20 20 7d 20 65 6c 73 65 69 66  ve].    } elseif
43d0: 20 7b 24 73 61 76 65 20 65 71 20 22 2d 22 7d 20   {$save eq "-"} 
43e0: 7b 0a 09 73 65 74 20 73 61 76 65 20 5b 6c 69 73  {..set save [lis
43f0: 74 20 61 70 70 6c 79 4e 6f 52 75 6c 65 5d 0a 20  t applyNoRule]. 
4400: 20 20 20 7d 20 65 6c 73 65 69 66 20 7b 5b 63 61     } elseif {[ca
4410: 74 63 68 20 7b 70 61 72 73 65 4f 66 66 73 65 74  tch {parseOffset
4420: 54 69 6d 65 20 24 73 61 76 65 7d 20 73 61 76 65  Time $save} save
4430: 32 5d 7d 20 7b 0a 09 6c 61 70 70 65 6e 64 20 66  2]} {..lappend f
4440: 6f 72 77 61 72 64 52 75 6c 65 52 65 66 73 28 24  orwardRuleRefs($
4450: 73 61 76 65 29 20 24 66 69 6c 65 4e 61 6d 65 20  save) $fileName 
4460: 24 6c 6e 6f 0a 09 73 65 74 20 73 61 76 65 20 5b  $lno..set save [
4470: 6c 69 73 74 20 61 70 70 6c 79 52 75 6c 65 73 20  list applyRules 
4480: 24 73 61 76 65 5d 0a 20 20 20 20 7d 20 65 6c 73  $save].    } els
4490: 65 20 7b 0a 09 73 65 74 20 73 61 76 65 20 5b 6c  e {..set save [l
44a0: 69 73 74 20 61 70 70 6c 79 44 53 54 4f 66 66 73  ist applyDSTOffs
44b0: 65 74 20 24 73 61 76 65 32 5d 0a 20 20 20 20 7d  et $save2].    }
44c0: 0a 20 20 20 20 6c 61 70 70 65 6e 64 20 7a 6f 6e  .    lappend zon
44d0: 65 73 28 24 7a 6f 6e 65 29 20 24 73 74 61 72 74  es($zone) $start
44e0: 20 24 67 6d 74 6f 66 66 20 24 73 61 76 65 20 24   $gmtoff $save $
44f0: 66 6f 72 6d 61 74 0a 20 20 20 20 69 66 20 7b 5b  format.    if {[
4500: 6c 6c 65 6e 67 74 68 20 24 77 6f 72 64 73 5d 20  llength $words] 
4510: 3e 3d 20 34 7d 20 7b 0a 09 72 65 74 75 72 6e 20  >= 4} {..return 
4520: 5b 70 61 72 73 65 55 6e 74 69 6c 20 5b 6c 72 61  [parseUntil [lra
4530: 6e 67 65 20 24 77 6f 72 64 73 20 33 20 65 6e 64  nge $words 3 end
4540: 5d 5d 0a 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a  ]].    } else {.
4550: 09 72 65 74 75 72 6e 20 7b 7d 0a 20 20 20 20 7d  .return {}.    }
4560: 0a 7d 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  .}..#-----------
4570: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
4580: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
4590: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
45a0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 0a 23 20  -----------.#.# 
45b0: 70 61 72 73 65 55 6e 74 69 6c 20 2d 2d 0a 23 0a  parseUntil --.#.
45c0: 23 09 50 61 72 73 65 73 20 74 68 65 20 27 55 4e  #.Parses the 'UN
45d0: 54 49 4c 27 20 70 61 72 74 20 6f 66 20 61 20 27  TIL' part of a '
45e0: 5a 6f 6e 65 27 20 64 69 72 65 63 74 69 76 65 2e  Zone' directive.
45f0: 0a 23 0a 23 20 50 61 72 61 6d 65 74 65 72 73 3a  .#.# Parameters:
4600: 0a 23 09 77 6f 72 64 73 20 2d 20 54 68 65 20 27  .#.words - The '
4610: 55 4e 54 49 4c 27 20 70 61 72 74 20 6f 66 20 74  UNTIL' part of t
4620: 68 65 20 64 69 72 65 63 74 69 65 2e 0a 23 0a 23  he directie..#.#
4630: 20 52 65 73 75 6c 74 73 3a 0a 23 09 52 65 74 75   Results:.#.Retu
4640: 72 6e 73 20 61 20 6c 69 73 74 20 63 6f 6d 70 72  rns a list compr
4650: 69 73 69 6e 67 20 74 68 65 20 79 65 61 72 2c 20  ising the year, 
4660: 74 68 65 20 6d 6f 6e 74 68 2c 20 74 68 65 20 64  the month, the d
4670: 61 79 2c 20 61 6e 64 0a 23 09 74 68 65 20 74 69  ay, and.#.the ti
4680: 6d 65 20 6f 66 20 64 61 79 2e 20 54 69 6d 65 20  me of day. Time 
4690: 6f 66 20 64 61 79 20 69 73 20 72 65 70 72 65 73  of day is repres
46a0: 65 6e 74 65 64 20 61 73 20 74 68 65 20 72 65 73  ented as the res
46b0: 75 6c 74 20 6f 66 0a 23 09 27 70 61 72 73 65 54  ult of.#.'parseT
46c0: 4f 44 27 2e 0a 23 0a 23 2d 2d 2d 2d 2d 2d 2d 2d  OD'..#.#--------
46d0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
46e0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
46f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
4700: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 0a  --------------..
4710: 70 72 6f 63 20 70 61 72 73 65 55 6e 74 69 6c 20  proc parseUntil 
4720: 7b 77 6f 72 64 73 7d 20 7b 0a 20 20 20 20 76 61  {words} {.    va
4730: 72 69 61 62 6c 65 20 66 69 72 73 74 59 65 61 72  riable firstYear
4740: 0a 0a 20 20 20 20 69 66 20 7b 5b 6c 6c 65 6e 67  ..    if {[lleng
4750: 74 68 20 24 77 6f 72 64 73 5d 20 3e 3d 20 31 7d  th $words] >= 1}
4760: 20 7b 0a 09 73 65 74 20 79 65 61 72 20 5b 6c 69   {..set year [li
4770: 6e 64 65 78 20 24 77 6f 72 64 73 20 30 5d 0a 09  ndex $words 0]..
4780: 69 66 20 7b 21 5b 73 74 72 69 6e 67 20 69 73 20  if {![string is 
4790: 69 6e 74 65 67 65 72 20 24 79 65 61 72 5d 7d 20  integer $year]} 
47a0: 7b 0a 09 20 20 20 20 65 72 72 6f 72 20 22 63 61  {..    error "ca
47b0: 6e 27 74 20 70 61 72 73 65 20 55 4e 54 49 4c 20  n't parse UNTIL 
47c0: 66 69 65 6c 64 20 5c 22 24 77 6f 72 64 73 5c 22  field \"$words\"
47d0: 22 0a 09 7d 0a 09 69 66 20 7b 21 5b 69 6e 66 6f  "..}..if {![info
47e0: 20 65 78 69 73 74 73 20 66 69 72 73 74 59 65 61   exists firstYea
47f0: 72 5d 20 7c 7c 20 24 79 65 61 72 20 3c 20 24 66  r] || $year < $f
4800: 69 72 73 74 59 65 61 72 7d 20 7b 0a 09 20 20 20  irstYear} {..   
4810: 20 73 65 74 20 66 69 72 73 74 59 65 61 72 20 24   set firstYear $
4820: 79 65 61 72 0a 09 7d 0a 20 20 20 20 7d 20 65 6c  year..}.    } el
4830: 73 65 20 7b 0a 09 73 65 74 20 79 65 61 72 20 22  se {..set year "
4840: 6d 61 78 69 6d 75 6d 22 0a 20 20 20 20 7d 0a 20  maximum".    }. 
4850: 20 20 20 69 66 20 7b 5b 6c 6c 65 6e 67 74 68 20     if {[llength 
4860: 24 77 6f 72 64 73 5d 20 3e 3d 20 32 7d 20 7b 0a  $words] >= 2} {.
4870: 09 73 65 74 20 6d 6f 6e 74 68 20 5b 6c 6f 6f 6b  .set month [look
4880: 75 70 4d 6f 6e 74 68 20 5b 6c 69 6e 64 65 78 20  upMonth [lindex 
4890: 24 77 6f 72 64 73 20 31 5d 5d 0a 20 20 20 20 7d  $words 1]].    }
48a0: 20 65 6c 73 65 20 7b 0a 09 73 65 74 20 6d 6f 6e   else {..set mon
48b0: 74 68 20 31 0a 20 20 20 20 7d 0a 20 20 20 20 69  th 1.    }.    i
48c0: 66 20 7b 5b 6c 6c 65 6e 67 74 68 20 24 77 6f 72  f {[llength $wor
48d0: 64 73 5d 20 3e 3d 20 33 7d 20 7b 0a 09 73 65 74  ds] >= 3} {..set
48e0: 20 64 61 79 20 5b 70 61 72 73 65 4f 4e 20 5b 6c   day [parseON [l
48f0: 69 6e 64 65 78 20 24 77 6f 72 64 73 20 32 5d 5d  index $words 2]]
4900: 0a 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 09 73  .    } else {..s
4910: 65 74 20 64 61 79 20 7b 6f 6e 44 61 79 4f 66 4d  et day {onDayOfM
4920: 6f 6e 74 68 20 31 7d 0a 20 20 20 20 7d 0a 20 20  onth 1}.    }.  
4930: 20 20 69 66 20 7b 5b 6c 6c 65 6e 67 74 68 20 24    if {[llength $
4940: 77 6f 72 64 73 5d 20 3e 3d 20 34 7d 20 7b 0a 09  words] >= 4} {..
4950: 73 65 74 20 74 6f 64 20 5b 70 61 72 73 65 54 4f  set tod [parseTO
4960: 44 20 5b 6c 69 6e 64 65 78 20 24 77 6f 72 64 73  D [lindex $words
4970: 20 33 5d 5d 0a 20 20 20 20 7d 20 65 6c 73 65 20   3]].    } else 
4980: 7b 0a 09 73 65 74 20 74 6f 64 20 7b 30 20 77 7d  {..set tod {0 w}
4990: 0a 20 20 20 20 7d 0a 20 20 20 20 72 65 74 75 72  .    }.    retur
49a0: 6e 20 5b 6c 69 73 74 20 24 79 65 61 72 20 24 6d  n [list $year $m
49b0: 6f 6e 74 68 20 24 64 61 79 20 24 74 6f 64 5d 0a  onth $day $tod].
49c0: 7d 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  }..#------------
49d0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
49e0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
49f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
4a00: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 0a 23 20 61  ----------.#.# a
4a10: 70 70 6c 79 4e 6f 52 75 6c 65 20 2d 2d 0a 23 0a  pplyNoRule --.#.
4a20: 23 09 47 65 6e 65 72 61 74 65 73 20 74 69 6d 65  #.Generates time
4a30: 20 7a 6f 6e 65 20 64 61 74 61 20 66 6f 72 20 61   zone data for a
4a40: 20 7a 6f 6e 65 20 77 69 74 68 6f 75 74 20 44 61   zone without Da
4a50: 79 6c 69 67 68 74 20 53 61 76 69 6e 67 0a 23 09  ylight Saving.#.
4a60: 54 69 6d 65 2e 0a 23 0a 23 20 50 61 72 61 6d 65  Time..#.# Parame
4a70: 74 65 72 73 3a 0a 23 09 79 65 61 72 20 2d 20 59  ters:.#.year - Y
4a80: 65 61 72 20 69 6e 20 77 68 69 63 68 20 74 68 65  ear in which the
4a90: 20 72 75 6c 65 20 61 70 70 6c 69 65 73 0a 23 09   rule applies.#.
4aa0: 73 74 61 72 74 53 65 63 73 20 2d 20 54 69 6d 65  startSecs - Time
4ab0: 20 61 74 20 77 68 69 63 68 20 74 68 65 20 72 75   at which the ru
4ac0: 6c 65 20 73 74 61 72 74 73 2e 0a 23 09 73 74 64  le starts..#.std
4ad0: 47 4d 54 4f 66 66 73 65 74 20 2d 20 4f 66 66 73  GMTOffset - Offs
4ae0: 65 74 20 66 72 6f 6d 20 47 72 65 65 6e 77 69 63  et from Greenwic
4af0: 68 20 70 72 69 6f 72 20 74 6f 20 74 68 65 20 73  h prior to the s
4b00: 74 61 72 74 20 6f 66 20 74 68 65 0a 23 09 09 20  tart of the.#.. 
4b10: 20 20 20 20 20 20 72 75 6c 65 0a 23 09 44 53 54        rule.#.DST
4b20: 4f 66 66 73 65 74 20 2d 20 4f 66 66 73 65 74 20  Offset - Offset 
4b30: 6f 66 20 44 61 79 6c 69 67 68 74 20 66 72 6f 6d  of Daylight from
4b40: 20 53 74 61 6e 64 61 72 64 20 70 72 69 6f 72 20   Standard prior 
4b50: 74 6f 20 74 68 65 0a 23 09 09 20 20 20 20 73 74  to the.#..    st
4b60: 61 72 74 20 6f 66 20 74 68 65 20 72 75 6c 65 2e  art of the rule.
4b70: 0a 23 09 6e 65 78 74 47 4d 54 4f 66 66 73 65 74  .#.nextGMTOffset
4b80: 20 2d 20 4f 66 66 73 65 74 20 66 72 6f 6d 20 47   - Offset from G
4b90: 72 65 65 6e 77 69 63 68 20 77 68 65 6e 20 74 68  reenwich when th
4ba0: 65 20 72 75 6c 65 20 69 73 20 69 6e 20 65 66 66  e rule is in eff
4bb0: 65 63 74 2e 0a 23 09 6e 61 6d 65 50 61 74 74 65  ect..#.namePatte
4bc0: 72 6e 20 2d 20 4e 61 6d 65 20 6f 66 20 74 68 65  rn - Name of the
4bd0: 20 74 69 6d 65 7a 6f 6e 65 2e 0a 23 09 75 6e 74   timezone..#.unt
4be0: 69 6c 20 2d 20 54 69 6d 65 20 61 74 20 77 68 69  il - Time at whi
4bf0: 63 68 20 74 68 65 20 72 75 6c 65 20 65 78 70 69  ch the rule expi
4c00: 72 65 73 2e 0a 23 09 70 6f 69 6e 74 73 56 61 72  res..#.pointsVar
4c10: 20 2d 20 4e 61 6d 65 20 6f 66 20 61 20 76 61 72   - Name of a var
4c20: 69 61 62 6c 65 20 69 6e 20 63 61 6c 6c 65 72 73  iable in callers
4c30: 20 73 63 6f 70 65 20 74 68 61 74 20 72 65 63 65   scope that rece
4c40: 69 76 65 73 0a 23 09 09 20 20 20 20 74 72 61 6e  ives.#..    tran
4c50: 73 69 74 69 6f 6e 20 74 69 6d 65 73 0a 23 0a 23  sition times.#.#
4c60: 20 52 65 73 75 6c 74 73 3a 0a 23 09 52 65 74 75   Results:.#.Retu
4c70: 72 6e 73 20 61 20 74 77 6f 20 65 6c 65 6d 65 6e  rns a two elemen
4c80: 74 20 6c 69 73 74 20 63 6f 6d 70 72 69 73 69 6e  t list comprisin
4c90: 67 20 27 6e 65 78 74 47 4d 54 4f 66 66 73 65 74  g 'nextGMTOffset
4ca0: 27 20 61 6e 64 0a 23 09 30 20 2d 20 74 68 65 20  ' and.#.0 - the 
4cb0: 7a 65 72 6f 20 69 6e 64 69 63 61 74 65 73 20 74  zero indicates t
4cc0: 68 61 74 20 44 61 79 6c 69 67 68 74 20 53 61 76  hat Daylight Sav
4cd0: 69 6e 67 20 54 69 6d 65 20 69 73 20 6e 6f 74 0a  ing Time is not.
4ce0: 23 09 69 6e 20 65 66 66 65 63 74 2e 0a 23 0a 23  #.in effect..#.#
4cf0: 20 53 69 64 65 20 65 66 66 65 63 74 73 3a 0a 23   Side effects:.#
4d00: 09 41 70 70 65 6e 64 73 20 61 20 72 6f 77 20 74  .Appends a row t
4d10: 6f 20 74 68 65 20 27 70 6f 69 6e 74 73 27 20 76  o the 'points' v
4d20: 61 72 69 61 62 6c 65 20 63 6f 6d 70 72 69 73 69  ariable comprisi
4d30: 6e 67 20 74 68 65 20 73 74 61 72 74 20 74 69 6d  ng the start tim
4d40: 65 2c 0a 23 09 74 68 65 20 6f 66 66 73 65 74 20  e,.#.the offset 
4d50: 66 72 6f 6d 20 47 4d 54 2c 20 61 20 7a 65 72 6f  from GMT, a zero
4d60: 20 28 69 6e 64 69 63 61 74 69 6e 67 20 74 68 61   (indicating tha
4d70: 74 20 44 53 54 20 69 73 20 6e 6f 74 20 69 6e 20  t DST is not in 
4d80: 65 66 66 65 63 74 29 2c 0a 23 09 61 6e 64 20 74  effect),.#.and t
4d90: 68 65 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 74  he name of the t
4da0: 69 6d 65 20 7a 6f 6e 65 2e 0a 23 0a 23 2d 2d 2d  ime zone..#.#---
4db0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
4dc0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
4dd0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
4de0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
4df0: 2d 2d 2d 0a 0a 70 72 6f 63 20 61 70 70 6c 79 4e  ---..proc applyN
4e00: 6f 52 75 6c 65 20 7b 79 65 61 72 20 73 74 61 72  oRule {year star
4e10: 74 53 65 63 73 20 73 74 64 47 4d 54 4f 66 66 73  tSecs stdGMTOffs
4e20: 65 74 20 44 53 54 4f 66 66 73 65 74 20 6e 65 78  et DSTOffset nex
4e30: 74 47 4d 54 4f 66 66 73 65 74 0a 09 09 20 20 6e  tGMTOffset...  n
4e40: 61 6d 65 50 61 74 74 65 72 6e 20 75 6e 74 69 6c  amePattern until
4e50: 20 70 6f 69 6e 74 73 56 61 72 7d 20 7b 0a 20 20   pointsVar} {.  
4e60: 20 20 75 70 76 61 72 20 31 20 24 70 6f 69 6e 74    upvar 1 $point
4e70: 73 56 61 72 20 70 6f 69 6e 74 73 0a 20 20 20 20  sVar points.    
4e80: 6c 61 70 70 65 6e 64 20 70 6f 69 6e 74 73 20 24  lappend points $
4e90: 73 74 61 72 74 53 65 63 73 20 24 6e 65 78 74 47  startSecs $nextG
4ea0: 4d 54 4f 66 66 73 65 74 20 30 20 5c 0a 09 20 20  MTOffset 0 \..  
4eb0: 20 20 5b 63 6f 6e 76 65 72 74 4e 61 6d 65 50 61    [convertNamePa
4ec0: 74 74 65 72 6e 20 24 6e 61 6d 65 50 61 74 74 65  ttern $namePatte
4ed0: 72 6e 20 2d 5d 0a 20 20 20 20 72 65 74 75 72 6e  rn -].    return
4ee0: 20 5b 6c 69 73 74 20 24 6e 65 78 74 47 4d 54 4f   [list $nextGMTO
4ef0: 66 66 73 65 74 20 30 5d 0a 7d 0a 0a 23 2d 2d 2d  ffset 0].}..#---
4f00: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
4f10: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
4f20: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
4f30: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
4f40: 2d 2d 2d 0a 23 0a 23 20 61 70 70 6c 79 44 53 54  ---.#.# applyDST
4f50: 4f 66 66 73 65 74 20 2d 2d 0a 23 0a 23 09 47 65  Offset --.#.#.Ge
4f60: 6e 65 72 61 74 65 73 20 74 69 6d 65 20 7a 6f 6e  nerates time zon
4f70: 65 20 64 61 74 61 20 66 6f 72 20 61 20 7a 6f 6e  e data for a zon
4f80: 65 20 77 69 74 68 20 70 65 72 6d 61 6e 65 6e 74  e with permanent
4f90: 20 44 61 79 6c 69 67 68 74 0a 23 09 53 61 76 69   Daylight.#.Savi
4fa0: 6e 67 20 54 69 6d 65 2e 0a 23 0a 23 20 50 61 72  ng Time..#.# Par
4fb0: 61 6d 65 74 65 72 73 3a 0a 23 09 6e 65 78 74 44  ameters:.#.nextD
4fc0: 53 54 4f 66 66 73 65 74 20 2d 20 4f 66 66 73 65  STOffset - Offse
4fd0: 74 20 6f 66 20 44 61 79 6c 69 67 68 74 20 66 72  t of Daylight fr
4fe0: 6f 6d 20 53 74 61 6e 64 61 72 64 20 77 68 69 6c  om Standard whil
4ff0: 65 20 74 68 65 0a 23 09 09 09 72 75 6c 65 20 69  e the.#...rule i
5000: 73 20 69 6e 20 65 66 66 65 63 74 2e 0a 23 09 79  s in effect..#.y
5010: 65 61 72 20 2d 20 59 65 61 72 20 69 6e 20 77 68  ear - Year in wh
5020: 69 63 68 20 74 68 65 20 72 75 6c 65 20 61 70 70  ich the rule app
5030: 6c 69 65 73 0a 23 09 73 74 61 72 74 53 65 63 73  lies.#.startSecs
5040: 20 2d 20 54 69 6d 65 20 61 74 20 77 68 69 63 68   - Time at which
5050: 20 74 68 65 20 72 75 6c 65 20 73 74 61 72 74 73   the rule starts
5060: 2e 0a 23 09 73 74 64 47 4d 54 4f 66 66 73 65 74  ..#.stdGMTOffset
5070: 20 2d 20 4f 66 66 73 65 74 20 66 72 6f 6d 20 47   - Offset from G
5080: 72 65 65 6e 77 69 63 68 20 70 72 69 6f 72 20 74  reenwich prior t
5090: 6f 20 74 68 65 20 73 74 61 72 74 20 6f 66 20 74  o the start of t
50a0: 68 65 0a 23 09 09 20 20 20 20 20 20 20 72 75 6c  he.#..       rul
50b0: 65 0a 23 09 44 53 54 4f 66 66 73 65 74 20 2d 20  e.#.DSTOffset - 
50c0: 4f 66 66 73 65 74 20 6f 66 20 44 61 79 6c 69 67  Offset of Daylig
50d0: 68 74 20 66 72 6f 6d 20 53 74 61 6e 64 61 72 64  ht from Standard
50e0: 20 70 72 69 6f 72 20 74 6f 20 74 68 65 0a 23 09   prior to the.#.
50f0: 09 20 20 20 20 73 74 61 72 74 20 6f 66 20 74 68  .    start of th
5100: 65 20 72 75 6c 65 2e 0a 23 09 6e 65 78 74 47 4d  e rule..#.nextGM
5110: 54 4f 66 66 73 65 74 20 2d 20 4f 66 66 73 65 74  TOffset - Offset
5120: 20 66 72 6f 6d 20 47 72 65 65 6e 77 69 63 68 20   from Greenwich 
5130: 77 68 65 6e 20 74 68 65 20 72 75 6c 65 20 69 73  when the rule is
5140: 20 69 6e 20 65 66 66 65 63 74 2e 0a 23 09 6e 61   in effect..#.na
5150: 6d 65 50 61 74 74 65 72 6e 20 2d 20 4e 61 6d 65  mePattern - Name
5160: 20 6f 66 20 74 68 65 20 74 69 6d 65 7a 6f 6e 65   of the timezone
5170: 2e 0a 23 09 75 6e 74 69 6c 20 2d 20 54 69 6d 65  ..#.until - Time
5180: 20 61 74 20 77 68 69 63 68 20 74 68 65 20 72 75   at which the ru
5190: 6c 65 20 65 78 70 69 72 65 73 2e 0a 23 09 70 6f  le expires..#.po
51a0: 69 6e 74 73 56 61 72 20 2d 20 4e 61 6d 65 20 6f  intsVar - Name o
51b0: 66 20 61 20 76 61 72 69 61 62 6c 65 20 69 6e 20  f a variable in 
51c0: 63 61 6c 6c 65 72 73 20 73 63 6f 70 65 20 74 68  callers scope th
51d0: 61 74 20 72 65 63 65 69 76 65 73 0a 23 09 09 20  at receives.#.. 
51e0: 20 20 20 74 72 61 6e 73 69 74 69 6f 6e 20 74 69     transition ti
51f0: 6d 65 73 0a 23 0a 23 20 52 65 73 75 6c 74 73 3a  mes.#.# Results:
5200: 0a 23 09 52 65 74 75 72 6e 73 20 61 20 74 77 6f  .#.Returns a two
5210: 20 65 6c 65 6d 65 6e 74 20 6c 69 73 74 20 63 6f   element list co
5220: 6d 70 72 69 73 69 6e 67 20 27 6e 65 78 74 47 4d  mprising 'nextGM
5230: 54 4f 66 66 73 65 74 27 20 61 6e 64 0a 23 09 27  TOffset' and.#.'
5240: 6e 65 78 74 44 53 54 4f 66 66 73 65 74 27 2e 0a  nextDSTOffset'..
5250: 23 0a 23 20 53 69 64 65 20 65 66 66 65 63 74 73  #.# Side effects
5260: 3a 0a 23 09 41 70 70 65 6e 64 73 20 61 20 72 6f  :.#.Appends a ro
5270: 77 20 74 6f 20 74 68 65 20 27 70 6f 69 6e 74 73  w to the 'points
5280: 27 20 76 61 72 69 61 62 6c 65 20 63 6f 6d 70 72  ' variable compr
5290: 69 73 69 6e 67 20 74 68 65 20 73 74 61 72 74 20  ising the start 
52a0: 74 69 6d 65 2c 0a 23 09 74 68 65 20 6f 66 66 73  time,.#.the offs
52b0: 65 74 20 66 72 6f 6d 20 47 4d 54 2c 20 61 20 6f  et from GMT, a o
52c0: 6e 65 20 28 69 6e 64 69 63 61 74 69 6e 67 20 74  ne (indicating t
52d0: 68 61 74 20 44 53 54 20 69 73 20 69 6e 20 65 66  hat DST is in ef
52e0: 66 65 63 74 29 2c 0a 23 09 61 6e 64 20 74 68 65  fect),.#.and the
52f0: 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 74 69 6d   name of the tim
5300: 65 20 7a 6f 6e 65 2e 0a 23 0a 23 2d 2d 2d 2d 2d  e zone..#.#-----
5310: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
5320: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
5330: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
5340: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
5350: 2d 0a 0a 70 72 6f 63 20 61 70 70 6c 79 44 53 54  -..proc applyDST
5360: 4f 66 66 73 65 74 20 7b 6e 65 78 74 44 53 54 4f  Offset {nextDSTO
5370: 66 66 73 65 74 20 79 65 61 72 20 73 74 61 72 74  ffset year start
5380: 53 65 63 73 0a 09 09 20 20 20 20 20 73 74 64 47  Secs...     stdG
5390: 4d 54 4f 66 66 73 65 74 20 44 53 54 4f 66 66 73  MTOffset DSTOffs
53a0: 65 74 20 6e 65 78 74 47 4d 54 4f 66 66 73 65 74  et nextGMTOffset
53b0: 0a 09 09 20 20 20 20 20 6e 61 6d 65 50 61 74 74  ...     namePatt
53c0: 65 72 6e 20 75 6e 74 69 6c 20 70 6f 69 6e 74 73  ern until points
53d0: 56 61 72 7d 20 7b 0a 20 20 20 20 75 70 76 61 72  Var} {.    upvar
53e0: 20 31 20 24 70 6f 69 6e 74 73 56 61 72 20 70 6f   1 $pointsVar po
53f0: 69 6e 74 73 0a 20 20 20 20 6c 61 70 70 65 6e 64  ints.    lappend
5400: 20 70 6f 69 6e 74 73 20 5c 0a 09 20 20 20 20 24   points \..    $
5410: 73 74 61 72 74 53 65 63 73 20 5c 0a 09 20 20 20  startSecs \..   
5420: 20 5b 65 78 70 72 20 7b 24 6e 65 78 74 47 4d 54   [expr {$nextGMT
5430: 4f 66 66 73 65 74 20 2b 20 24 6e 65 78 74 44 53  Offset + $nextDS
5440: 54 4f 66 66 73 65 74 7d 5d 20 5c 0a 09 20 20 20  TOffset}] \..   
5450: 20 31 20 5c 0a 09 20 20 20 20 5b 63 6f 6e 76 65   1 \..    [conve
5460: 72 74 4e 61 6d 65 50 61 74 74 65 72 6e 20 24 6e  rtNamePattern $n
5470: 61 6d 65 50 61 74 74 65 72 6e 20 53 5d 0a 20 20  amePattern S].  
5480: 20 20 72 65 74 75 72 6e 20 5b 6c 69 73 74 20 24    return [list $
5490: 6e 65 78 74 47 4d 54 4f 66 66 73 65 74 20 24 6e  nextGMTOffset $n
54a0: 65 78 74 44 53 54 4f 66 66 73 65 74 5d 0a 7d 0a  extDSTOffset].}.
54b0: 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  .#--------------
54c0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
54d0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
54e0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
54f0: 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 0a 23 20 61 70 70  --------.#.# app
5500: 6c 79 52 75 6c 65 73 20 2d 2d 0a 23 0a 23 09 41  lyRules --.#.#.A
5510: 70 70 6c 69 65 73 20 61 20 72 75 6c 65 20 73 65  pplies a rule se
5520: 74 20 74 6f 20 61 20 74 69 6d 65 20 7a 6f 6e 65  t to a time zone
5530: 20 66 6f 72 20 61 20 67 69 76 65 6e 20 72 61 6e   for a given ran
5540: 67 65 20 6f 66 20 74 69 6d 65 0a 23 0a 23 20 50  ge of time.#.# P
5550: 61 72 61 6d 65 74 65 72 73 3a 0a 23 09 72 75 6c  arameters:.#.rul
5560: 65 53 65 74 20 2d 20 4e 61 6d 65 20 6f 66 20 74  eSet - Name of t
5570: 68 65 20 72 75 6c 65 20 73 65 74 20 74 6f 20 61  he rule set to a
5580: 70 70 6c 79 0a 23 09 79 65 61 72 20 2d 20 53 74  pply.#.year - St
5590: 61 72 74 69 6e 67 20 79 65 61 72 20 66 6f 72 20  arting year for 
55a0: 74 68 65 20 72 75 6c 65 73 0a 23 09 73 74 61 72  the rules.#.star
55b0: 74 53 65 63 73 20 2d 20 54 69 6d 65 20 61 74 20  tSecs - Time at 
55c0: 77 68 69 63 68 20 74 68 65 20 72 75 6c 65 73 20  which the rules 
55d0: 62 65 67 69 6e 20 74 6f 20 61 70 70 6c 79 0a 23  begin to apply.#
55e0: 09 73 74 64 47 4d 54 4f 66 66 73 65 74 20 2d 20  .stdGMTOffset - 
55f0: 4f 66 66 73 65 74 20 66 72 6f 6d 20 47 72 65 65  Offset from Gree
5600: 6e 77 69 63 68 20 70 72 69 6f 72 20 74 6f 20 74  nwich prior to t
5610: 68 65 20 73 74 61 72 74 20 6f 66 20 74 68 65 0a  he start of the.
5620: 23 09 09 20 20 20 20 20 20 20 72 75 6c 65 73 2e  #..       rules.
5630: 0a 23 09 44 53 54 4f 66 66 73 65 74 20 2d 20 4f  .#.DSTOffset - O
5640: 66 66 73 65 74 20 6f 66 20 44 61 79 6c 69 67 68  ffset of Dayligh
5650: 74 20 66 72 6f 6d 20 53 74 61 6e 64 61 72 64 20  t from Standard 
5660: 70 72 69 6f 72 20 74 6f 20 74 68 65 0a 23 09 09  prior to the.#..
5670: 20 20 20 20 73 74 61 72 74 20 6f 66 20 74 68 65      start of the
5680: 20 72 75 6c 65 73 2e 0a 23 09 6e 65 78 74 47 4d   rules..#.nextGM
5690: 54 4f 66 66 73 65 74 20 2d 20 4f 66 66 73 65 74  TOffset - Offset
56a0: 20 66 72 6f 6d 20 47 72 65 65 6e 77 69 63 68 20   from Greenwich 
56b0: 77 68 65 6e 20 74 68 65 20 72 75 6c 65 73 20 61  when the rules a
56c0: 72 65 20 69 6e 20 65 66 66 65 63 74 2e 0a 23 09  re in effect..#.
56d0: 6e 61 6d 65 50 61 74 74 65 72 6e 20 2d 20 4e 61  namePattern - Na
56e0: 6d 65 20 70 61 74 74 65 72 6e 20 66 6f 72 20 74  me pattern for t
56f0: 68 65 20 74 69 6d 65 20 7a 6f 6e 65 2e 0a 23 09  he time zone..#.
5700: 75 6e 74 69 6c 20 2d 20 54 69 6d 65 20 61 74 20  until - Time at 
5710: 77 68 69 63 68 20 74 68 65 20 72 75 6c 65 20 73  which the rule s
5720: 65 74 20 65 78 70 69 72 65 73 2e 0a 23 09 70 6f  et expires..#.po
5730: 69 6e 74 73 56 61 72 20 2d 20 4e 61 6d 65 20 6f  intsVar - Name o
5740: 66 20 61 20 76 61 72 69 61 62 6c 65 20 69 6e 20  f a variable in 
5750: 63 61 6c 6c 65 72 73 20 73 63 6f 70 65 20 74 68  callers scope th
5760: 61 74 20 72 65 63 65 69 76 65 73 0a 23 09 09 20  at receives.#.. 
5770: 20 20 20 74 72 61 6e 73 69 74 69 6f 6e 20 74 69     transition ti
5780: 6d 65 73 0a 23 0a 23 20 52 65 73 75 6c 74 73 3a  mes.#.# Results:
5790: 0a 23 09 52 65 74 75 72 6e 73 20 61 20 74 77 6f  .#.Returns a two
57a0: 20 65 6c 65 6d 65 6e 74 20 6c 69 73 74 20 63 6f   element list co
57b0: 6d 70 72 69 73 69 6e 67 20 74 68 65 20 6f 66 66  mprising the off
57c0: 73 65 74 20 66 72 6f 6d 20 47 4d 54 0a 23 09 74  set from GMT.#.t
57d0: 6f 20 53 74 61 6e 64 61 72 64 20 61 6e 64 20 74  o Standard and t
57e0: 68 65 20 6f 66 66 73 65 74 20 66 72 6f 6d 20 53  he offset from S
57f0: 74 61 6e 64 61 72 64 20 74 6f 20 44 61 79 6c 69  tandard to Dayli
5800: 67 68 74 20 28 69 66 20 44 53 54 0a 23 09 69 73  ght (if DST.#.is
5810: 20 69 6e 20 65 66 66 65 63 74 29 20 61 74 20 74   in effect) at t
5820: 68 65 20 65 6e 64 20 6f 66 20 74 68 65 20 70 65  he end of the pe
5830: 72 69 6f 64 20 69 6e 20 77 68 69 63 68 20 74 68  riod in which th
5840: 65 20 72 75 6c 65 73 20 61 70 70 6c 79 0a 23 0a  e rules apply.#.
5850: 23 20 53 69 64 65 20 65 66 66 65 63 74 73 3a 0a  # Side effects:.
5860: 23 09 41 70 70 65 6e 64 73 20 6f 6e 65 20 6f 72  #.Appends one or
5870: 20 6d 6f 72 65 20 72 6f 77 73 20 74 6f 20 74 68   more rows to th
5880: 65 20 27 70 6f 69 6e 74 73 27 20 76 61 72 69 61  e 'points' varia
5890: 62 6c 65 2c 20 65 61 63 68 20 6f 66 20 77 68 69  ble, each of whi
58a0: 63 68 0a 23 09 63 6f 6d 70 72 69 73 65 73 20 61  ch.#.comprises a
58b0: 20 74 72 61 6e 73 69 74 69 6f 6e 20 74 69 6d 65   transition time
58c0: 2c 20 74 68 65 20 6f 66 66 73 65 74 20 66 72 6f  , the offset fro
58d0: 6d 20 47 4d 54 20 74 68 61 74 20 69 73 0a 23 09  m GMT that is.#.
58e0: 69 6e 20 65 66 66 65 63 74 20 61 66 74 65 72 20  in effect after 
58f0: 74 68 65 20 74 72 61 6e 73 69 74 69 6f 6e 2c 20  the transition, 
5900: 61 20 66 6c 61 67 20 66 6f 72 20 77 68 65 74 68  a flag for wheth
5910: 65 72 20 44 53 54 20 69 73 20 69 6e 0a 23 09 65  er DST is in.#.e
5920: 66 66 65 63 74 2c 20 61 6e 64 20 74 68 65 20 6e  ffect, and the n
5930: 61 6d 65 20 6f 66 20 74 68 65 20 74 69 6d 65 20  ame of the time 
5940: 7a 6f 6e 65 2e 0a 23 0a 23 2d 2d 2d 2d 2d 2d 2d  zone..#.#-------
5950: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
5960: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
5970: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
5980: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a  ---------------.
5990: 0a 70 72 6f 63 20 61 70 70 6c 79 52 75 6c 65 73  .proc applyRules
59a0: 20 7b 72 75 6c 65 53 65 74 20 79 65 61 72 20 73   {ruleSet year s
59b0: 74 61 72 74 53 65 63 73 20 73 74 64 47 4d 54 4f  tartSecs stdGMTO
59c0: 66 66 73 65 74 20 44 53 54 4f 66 66 73 65 74 20  ffset DSTOffset 
59d0: 6e 65 78 74 47 4d 54 4f 66 66 73 65 74 0a 09 09  nextGMTOffset...
59e0: 20 6e 61 6d 65 50 61 74 74 65 72 6e 20 75 6e 74   namePattern unt
59f0: 69 6c 20 70 6f 69 6e 74 73 56 61 72 7d 20 7b 0a  il pointsVar} {.
5a00: 20 20 20 20 76 61 72 69 61 62 6c 65 20 64 6f 6e      variable don
5a10: 65 0a 20 20 20 20 76 61 72 69 61 62 6c 65 20 72  e.    variable r
5a20: 75 6c 65 73 0a 20 20 20 20 76 61 72 69 61 62 6c  ules.    variabl
5a30: 65 20 6d 61 78 79 65 61 72 0a 0a 20 20 20 20 75  e maxyear..    u
5a40: 70 76 61 72 20 31 20 24 70 6f 69 6e 74 73 56 61  pvar 1 $pointsVa
5a50: 72 20 70 6f 69 6e 74 73 0a 0a 20 20 20 20 23 20  r points..    # 
5a60: 45 78 74 72 61 63 74 20 74 68 65 20 72 75 6c 65  Extract the rule
5a70: 73 20 74 68 61 74 20 61 70 70 6c 79 20 74 6f 20  s that apply to 
5a80: 74 68 65 20 63 75 72 72 65 6e 74 20 79 65 61 72  the current year
5a90: 2c 20 61 6e 64 20 74 68 65 20 6e 75 6d 62 65 72  , and the number
5aa0: 0a 20 20 20 20 23 20 6f 66 20 72 75 6c 65 73 20  .    # of rules 
5ab0: 28 6e 6f 77 20 6f 72 20 69 6e 20 66 75 74 75 72  (now or in futur
5ac0: 65 29 20 74 68 61 74 20 77 69 6c 6c 20 65 6e 64  e) that will end
5ad0: 20 61 74 20 61 20 73 70 65 63 69 66 69 63 20 79   at a specific y
5ae0: 65 61 72 2e 0a 20 20 20 20 23 20 49 67 6e 6f 72  ear..    # Ignor
5af0: 65 20 72 75 6c 65 73 20 65 6e 74 69 72 65 6c 79  e rules entirely
5b00: 20 69 6e 20 74 68 65 20 70 61 73 74 2e 0a 0a 20   in the past... 
5b10: 20 20 20 6c 61 73 73 69 67 6e 20 5b 64 69 76 69     lassign [divi
5b20: 64 65 52 75 6c 65 73 20 24 72 75 6c 65 53 65 74  deRules $ruleSet
5b30: 20 24 79 65 61 72 5d 20 63 75 72 72 65 6e 74 52   $year] currentR
5b40: 75 6c 65 73 20 6e 53 75 6e 73 65 74 52 75 6c 65  ules nSunsetRule
5b50: 73 0a 0a 20 20 20 20 23 20 49 66 20 74 68 65 20  s..    # If the 
5b60: 66 69 72 73 74 20 74 72 61 6e 73 69 74 69 6f 6e  first transition
5b70: 20 69 73 20 6c 61 74 65 72 20 74 68 61 6e 20 24   is later than $
5b80: 73 74 61 72 74 53 65 63 73 2c 20 61 6e 64 20 24  startSecs, and $
5b90: 73 74 64 47 4d 54 4f 66 66 73 65 74 20 69 73 0a  stdGMTOffset is.
5ba0: 20 20 20 20 23 20 64 69 66 66 65 72 65 6e 74 20      # different 
5bb0: 66 72 6f 6d 20 24 6e 65 78 74 47 4d 54 4f 66 66  from $nextGMTOff
5bc0: 73 65 74 2c 20 77 65 20 77 69 6c 6c 20 6e 65 65  set, we will nee
5bd0: 64 20 61 6e 20 69 6e 69 74 69 61 6c 20 72 65 63  d an initial rec
5be0: 6f 72 64 20 6c 69 6b 65 3a 0a 20 20 20 20 23 09  ord like:.    #.
5bf0: 20 6c 61 70 70 65 6e 64 20 70 6f 69 6e 74 73 20   lappend points 
5c00: 24 73 74 61 72 74 53 65 63 73 20 24 73 74 64 47  $startSecs $stdG
5c10: 4d 54 4f 66 66 73 65 74 20 30 20 5c 0a 20 20 20  MTOffset 0 \.   
5c20: 20 23 09 09 09 5b 63 6f 6e 76 65 72 74 4e 61 6d   #...[convertNam
5c30: 65 50 61 74 74 65 72 6e 20 24 6e 61 6d 65 50 61  ePattern $namePa
5c40: 74 74 65 72 6e 20 2d 5d 0a 0a 20 20 20 20 73 65  ttern -]..    se
5c50: 74 20 64 69 64 54 72 61 6e 73 69 74 69 6f 6e 49  t didTransitionI
5c60: 6e 20 66 61 6c 73 65 0a 0a 20 20 20 20 23 20 44  n false..    # D
5c70: 65 74 65 72 6d 69 6e 65 20 74 68 65 20 6c 65 74  etermine the let
5c80: 74 65 72 20 74 6f 20 75 73 65 20 69 6e 20 53 74  ter to use in St
5c90: 61 6e 64 61 72 64 20 54 69 6d 65 0a 0a 20 20 20  andard Time..   
5ca0: 20 73 65 74 20 70 72 65 76 4c 65 74 74 65 72 20   set prevLetter 
5cb0: 22 22 0a 20 20 20 20 66 6f 72 65 61 63 68 20 7b  "".    foreach {
5cc0: 0a 09 66 72 6f 6d 59 65 61 72 20 74 6f 59 65 61  ..fromYear toYea
5cd0: 72 20 79 65 61 72 54 79 70 65 20 6d 6f 6e 74 68  r yearType month
5ce0: 49 6e 20 64 61 79 53 70 65 63 4f 6e 20 74 69 6d  In daySpecOn tim
5cf0: 65 41 74 20 73 61 76 65 20 6c 65 74 74 65 72 0a  eAt save letter.
5d00: 20 20 20 20 7d 20 24 72 75 6c 65 73 28 24 72 75      } $rules($ru
5d10: 6c 65 53 65 74 29 20 7b 0a 09 69 66 20 7b 24 73  leSet) {..if {$s
5d20: 61 76 65 20 3d 3d 20 30 7d 20 7b 0a 09 20 20 20  ave == 0} {..   
5d30: 20 73 65 74 20 70 72 65 76 4c 65 74 74 65 72 20   set prevLetter 
5d40: 24 6c 65 74 74 65 72 0a 09 20 20 20 20 62 72 65  $letter..    bre
5d50: 61 6b 0a 09 7d 0a 20 20 20 20 7d 0a 0a 20 20 20  ak..}.    }..   
5d60: 20 23 20 57 61 6c 6b 20 74 68 72 6f 75 67 68 20   # Walk through 
5d70: 65 61 63 68 20 79 65 61 72 20 69 6e 20 74 75 72  each year in tur
5d80: 6e 2e 20 54 68 69 73 20 6c 6f 6f 70 20 77 69 6c  n. This loop wil
5d90: 6c 20 62 72 65 61 6b 20 77 68 65 6e 0a 20 20 20  l break when.   
5da0: 20 23 09 20 28 61 29 20 74 68 65 20 27 75 6e 74   #. (a) the 'unt
5db0: 69 6c 27 20 74 69 6d 65 20 69 73 20 70 61 73 73  il' time is pass
5dc0: 65 64 0a 20 20 20 20 23 20 6f 72 20 28 62 29 20  ed.    # or (b) 
5dd0: 74 68 65 20 27 75 6e 74 69 6c 27 20 74 69 6d 65  the 'until' time
5de0: 20 69 73 20 65 6d 70 74 79 20 61 6e 64 20 61 6c   is empty and al
5df0: 6c 20 72 65 6d 61 69 6e 69 6e 67 20 72 75 6c 65  l remaining rule
5e00: 73 20 65 78 74 65 6e 64 20 74 6f 0a 20 20 20 20  s extend to.    
5e10: 23 09 20 20 20 20 20 74 68 65 20 65 6e 64 20 6f  #.     the end o
5e20: 66 20 74 69 6d 65 0a 0a 20 20 20 20 73 65 74 20  f time..    set 
5e30: 73 74 64 47 4d 54 4f 66 66 73 65 74 20 24 6e 65  stdGMTOffset $ne
5e40: 78 74 47 4d 54 4f 66 66 73 65 74 0a 0a 20 20 20  xtGMTOffset..   
5e50: 20 23 20 63 6f 6e 76 65 72 74 20 22 75 6e 74 69   # convert "unti
5e60: 6c 22 20 74 6f 20 73 65 63 6f 6e 64 73 20 66 72  l" to seconds fr
5e70: 6f 6d 20 65 70 6f 63 68 20 69 6e 20 63 75 72 72  om epoch in curr
5e80: 65 6e 74 20 74 69 6d 65 20 7a 6f 6e 65 0a 0a 20  ent time zone.. 
5e90: 20 20 20 69 66 20 7b 24 75 6e 74 69 6c 20 6e 65     if {$until ne
5ea0: 20 22 22 7d 20 7b 0a 09 6c 61 73 73 69 67 6e 20   ""} {..lassign 
5eb0: 24 75 6e 74 69 6c 20 75 6e 74 69 6c 59 65 61 72  $until untilYear
5ec0: 20 75 6e 74 69 6c 4d 6f 6e 74 68 20 75 6e 74 69   untilMonth unti
5ed0: 6c 44 61 79 53 70 65 63 20 75 6e 74 69 6c 54 69  lDaySpec untilTi
5ee0: 6d 65 4f 66 44 61 79 0a 09 6c 61 70 70 65 6e 64  meOfDay..lappend
5ef0: 20 75 6e 74 69 6c 44 61 79 53 70 65 63 20 24 75   untilDaySpec $u
5f00: 6e 74 69 6c 59 65 61 72 20 24 75 6e 74 69 6c 4d  ntilYear $untilM
5f10: 6f 6e 74 68 0a 09 73 65 74 20 75 6e 74 69 6c 4a  onth..set untilJ
5f20: 43 44 20 5b 65 76 61 6c 20 24 75 6e 74 69 6c 44  CD [eval $untilD
5f30: 61 79 53 70 65 63 5d 0a 09 73 65 74 20 75 6e 74  aySpec]..set unt
5f40: 69 6c 42 61 73 65 53 65 63 73 20 5b 65 78 70 72  ilBaseSecs [expr
5f50: 20 7b 0a 09 09 77 69 64 65 28 38 36 34 30 30 29   {...wide(86400)
5f60: 20 2a 20 77 69 64 65 28 24 75 6e 74 69 6c 4a 43   * wide($untilJC
5f70: 44 29 20 2d 20 32 31 30 38 36 36 38 30 33 32 30  D) - 21086680320
5f80: 30 20 7d 5d 0a 09 73 65 74 20 75 6e 74 69 6c 53  0 }]..set untilS
5f90: 65 63 73 20 5b 63 6f 6e 76 65 72 74 54 69 6d 65  ecs [convertTime
5fa0: 4f 66 44 61 79 20 24 75 6e 74 69 6c 42 61 73 65  OfDay $untilBase
5fb0: 53 65 63 73 20 24 73 74 64 47 4d 54 4f 66 66 73  Secs $stdGMTOffs
5fc0: 65 74 20 5c 0a 09 09 24 44 53 54 4f 66 66 73 65  et \...$DSTOffse
5fd0: 74 20 7b 2a 7d 24 75 6e 74 69 6c 54 69 6d 65 4f  t {*}$untilTimeO
5fe0: 66 44 61 79 5d 0a 20 20 20 20 7d 0a 0a 20 20 20  fDay].    }..   
5ff0: 20 73 65 74 20 6f 72 69 67 53 74 61 72 74 53 65   set origStartSe
6000: 63 73 20 24 73 74 61 72 74 53 65 63 73 0a 0a 20  cs $startSecs.. 
6010: 20 20 20 77 68 69 6c 65 20 7b 28 24 75 6e 74 69     while {($unti
6020: 6c 20 6e 65 20 22 22 20 26 26 20 24 73 74 61 72  l ne "" && $star
6030: 74 53 65 63 73 20 3c 20 24 75 6e 74 69 6c 53 65  tSecs < $untilSe
6040: 63 73 29 0a 09 20 20 20 20 7c 7c 20 28 24 75 6e  cs)..    || ($un
6050: 74 69 6c 20 65 71 20 22 22 20 26 26 20 28 24 6e  til eq "" && ($n
6060: 53 75 6e 73 65 74 52 75 6c 65 73 20 3e 20 30 20  SunsetRules > 0 
6070: 7c 7c 20 24 79 65 61 72 20 3c 20 24 6d 61 78 79  || $year < $maxy
6080: 65 61 72 29 29 7d 20 7b 0a 09 73 65 74 20 72 65  ear))} {..set re
6090: 6d 61 69 6e 69 6e 67 52 75 6c 65 73 20 24 63 75  mainingRules $cu
60a0: 72 72 65 6e 74 52 75 6c 65 73 0a 09 77 68 69 6c  rrentRules..whil
60b0: 65 20 7b 5b 6c 6c 65 6e 67 74 68 20 24 72 65 6d  e {[llength $rem
60c0: 61 69 6e 69 6e 67 52 75 6c 65 73 5d 20 3e 20 30  ainingRules] > 0
60d0: 7d 20 7b 0a 0a 09 20 20 20 20 23 20 46 69 6e 64  } {...    # Find
60e0: 20 74 68 65 20 72 75 6c 65 20 77 69 74 68 20 74   the rule with t
60f0: 68 65 20 65 61 72 6c 69 65 73 74 20 73 74 61 72  he earliest star
6100: 74 20 74 69 6d 65 20 66 72 6f 6d 20 61 6d 6f 6e  t time from amon
6110: 67 20 74 68 65 0a 09 20 20 20 20 23 20 61 63 74  g the..    # act
6120: 69 76 65 20 72 75 6c 65 73 20 74 68 61 74 20 68  ive rules that h
6130: 61 76 65 6e 27 74 20 79 65 74 20 62 65 65 6e 20  aven't yet been 
6140: 70 72 6f 63 65 73 73 65 64 2e 0a 0a 09 20 20 20  processed....   
6150: 20 6c 61 73 73 69 67 6e 20 5b 66 69 6e 64 45 61   lassign [findEa
6160: 72 6c 69 65 73 74 52 75 6c 65 20 24 72 65 6d 61  rliestRule $rema
6170: 69 6e 69 6e 67 52 75 6c 65 73 20 24 79 65 61 72  iningRules $year
6180: 20 5c 0a 09 09 20 20 20 20 24 73 74 64 47 4d 54   \...    $stdGMT
6190: 4f 66 66 73 65 74 20 24 44 53 54 4f 66 66 73 65  Offset $DSTOffse
61a0: 74 5d 20 65 61 72 6c 69 65 73 74 53 65 63 73 20  t] earliestSecs 
61b0: 65 61 72 6c 69 65 73 74 49 6e 64 65 78 0a 0a 09  earliestIndex...
61c0: 20 20 20 20 73 65 74 20 65 6e 64 69 20 5b 65 78      set endi [ex
61d0: 70 72 20 7b 24 65 61 72 6c 69 65 73 74 49 6e 64  pr {$earliestInd
61e0: 65 78 20 2b 20 37 7d 5d 0a 09 20 20 20 20 73 65  ex + 7}]..    se
61f0: 74 20 72 75 6c 65 20 5b 6c 72 61 6e 67 65 20 24  t rule [lrange $
6200: 72 65 6d 61 69 6e 69 6e 67 52 75 6c 65 73 20 24  remainingRules $
6210: 65 61 72 6c 69 65 73 74 49 6e 64 65 78 20 24 65  earliestIndex $e
6220: 6e 64 69 5d 0a 09 20 20 20 20 6c 61 73 73 69 67  ndi]..    lassig
6230: 6e 20 24 72 75 6c 65 20 66 72 6f 6d 59 65 61 72  n $rule fromYear
6240: 20 74 6f 59 65 61 72 20 5c 0a 09 09 20 20 20 20   toYear \...    
6250: 79 65 61 72 54 79 70 65 20 6d 6f 6e 74 68 49 6e  yearType monthIn
6260: 20 64 61 79 53 70 65 63 4f 6e 20 74 69 6d 65 41   daySpecOn timeA
6270: 74 20 73 61 76 65 20 6c 65 74 74 65 72 0a 0a 09  t save letter...
6280: 20 20 20 20 23 20 54 65 73 74 20 69 66 20 74 68      # Test if th
6290: 65 20 72 75 6c 65 20 69 73 20 69 6e 20 65 66 66  e rule is in eff
62a0: 65 63 74 2e 0a 0a 09 20 20 20 20 69 66 20 7b 0a  ect....    if {.
62b0: 09 09 24 65 61 72 6c 69 65 73 74 53 65 63 73 20  ..$earliestSecs 
62c0: 3e 20 24 73 74 61 72 74 53 65 63 73 20 26 26 0a  > $startSecs &&.
62d0: 09 09 28 24 75 6e 74 69 6c 20 65 71 20 22 22 20  ..($until eq "" 
62e0: 7c 7c 20 24 65 61 72 6c 69 65 73 74 53 65 63 73  || $earliestSecs
62f0: 20 3c 20 24 75 6e 74 69 6c 53 65 63 73 29 0a 09   < $untilSecs)..
6300: 20 20 20 20 7d 20 7b 0a 09 09 23 20 54 65 73 74      } {...# Test
6310: 20 69 66 20 74 68 65 20 69 6e 69 74 69 61 6c 20   if the initial 
6320: 74 72 61 6e 73 69 74 69 6f 6e 20 68 61 73 20 62  transition has b
6330: 65 65 6e 20 64 6f 6e 65 2e 0a 09 09 23 20 49 66  een done....# If
6340: 20 6e 6f 74 2c 20 64 6f 20 69 74 20 6e 6f 77 2e   not, do it now.
6350: 0a 0a 09 09 69 66 20 7b 21 24 64 69 64 54 72 61  ....if {!$didTra
6360: 6e 73 69 74 69 6f 6e 49 6e 20 26 26 20 24 65 61  nsitionIn && $ea
6370: 72 6c 69 65 73 74 53 65 63 73 20 3e 20 24 6f 72  rliestSecs > $or
6380: 69 67 53 74 61 72 74 53 65 63 73 7d 20 7b 0a 09  igStartSecs} {..
6390: 09 20 20 20 20 73 65 74 20 6e 6d 20 5b 63 6f 6e  .    set nm [con
63a0: 76 65 72 74 4e 61 6d 65 50 61 74 74 65 72 6e 20  vertNamePattern 
63b0: 24 6e 61 6d 65 50 61 74 74 65 72 6e 20 24 70 72  $namePattern $pr
63c0: 65 76 4c 65 74 74 65 72 5d 0a 09 09 20 20 20 20  evLetter]...    
63d0: 6c 61 70 70 65 6e 64 20 70 6f 69 6e 74 73 20 5c  lappend points \
63e0: 0a 09 09 09 20 20 20 20 24 6f 72 69 67 53 74 61  ....    $origSta
63f0: 72 74 53 65 63 73 20 5c 0a 09 09 09 20 20 20 20  rtSecs \....    
6400: 5b 65 78 70 72 20 7b 24 73 74 64 47 4d 54 4f 66  [expr {$stdGMTOf
6410: 66 73 65 74 20 2b 20 24 44 53 54 4f 66 66 73 65  fset + $DSTOffse
6420: 74 7d 5d 20 5c 0a 09 09 09 20 20 20 20 30 20 5c  t}] \....    0 \
6430: 0a 09 09 09 20 20 20 20 24 6e 6d 0a 09 09 20 20  ....    $nm...  
6440: 20 20 73 65 74 20 64 69 64 54 72 61 6e 73 69 74    set didTransit
6450: 69 6f 6e 49 6e 20 74 72 75 65 0a 09 09 7d 0a 0a  ionIn true...}..
6460: 09 09 23 20 41 64 64 20 61 20 72 6f 77 20 74 6f  ..# Add a row to
6470: 20 27 70 6f 69 6e 74 73 27 20 66 6f 72 20 74 68   'points' for th
6480: 65 20 72 75 6c 65 0a 0a 09 09 73 65 74 20 6e 6d  e rule....set nm
6490: 20 5b 63 6f 6e 76 65 72 74 4e 61 6d 65 50 61 74   [convertNamePat
64a0: 74 65 72 6e 20 24 6e 61 6d 65 50 61 74 74 65 72  tern $namePatter
64b0: 6e 20 24 6c 65 74 74 65 72 5d 0a 09 09 6c 61 70  n $letter]...lap
64c0: 70 65 6e 64 20 70 6f 69 6e 74 73 20 5c 0a 09 09  pend points \...
64d0: 09 24 65 61 72 6c 69 65 73 74 53 65 63 73 20 5c  .$earliestSecs \
64e0: 0a 09 09 09 5b 65 78 70 72 20 7b 24 73 74 64 47  ....[expr {$stdG
64f0: 4d 54 4f 66 66 73 65 74 20 2b 20 24 73 61 76 65  MTOffset + $save
6500: 7d 5d 20 5c 0a 09 09 09 5b 65 78 70 72 20 7b 24  }] \....[expr {$
6510: 73 61 76 65 20 21 3d 20 30 7d 5d 20 5c 0a 09 09  save != 0}] \...
6520: 09 24 6e 6d 0a 09 20 20 20 20 7d 0a 0a 09 20 20  .$nm..    }...  
6530: 20 20 23 20 52 65 6d 6f 76 65 20 74 68 65 20 72    # Remove the r
6540: 75 6c 65 20 6a 75 73 74 20 61 70 70 6c 69 65 64  ule just applied
6550: 20 66 72 6f 6d 20 74 68 65 20 71 75 65 75 65 0a   from the queue.
6560: 0a 09 20 20 20 20 73 65 74 20 72 65 6d 61 69 6e  ..    set remain
6570: 69 6e 67 52 75 6c 65 73 20 5b 6c 72 65 70 6c 61  ingRules [lrepla
6580: 63 65 20 5c 0a 09 09 20 20 20 20 24 72 65 6d 61  ce \...    $rema
6590: 69 6e 69 6e 67 52 75 6c 65 73 5b 73 65 74 20 72  iningRules[set r
65a0: 65 6d 61 69 6e 69 6e 67 52 75 6c 65 73 20 7b 7d  emainingRules {}
65b0: 5d 20 5c 0a 09 09 20 20 20 20 24 65 61 72 6c 69  ] \...    $earli
65c0: 65 73 74 49 6e 64 65 78 20 24 65 6e 64 69 5d 0a  estIndex $endi].
65d0: 0a 09 20 20 20 20 23 20 55 70 64 61 74 65 20 63  ..    # Update c
65e0: 75 72 72 65 6e 74 20 44 53 54 20 6f 66 66 73 65  urrent DST offse
65f0: 74 20 61 6e 64 20 74 69 6d 65 20 7a 6f 6e 65 20  t and time zone 
6600: 6c 65 74 74 65 72 0a 0a 09 20 20 20 20 73 65 74  letter...    set
6610: 20 44 53 54 4f 66 66 73 65 74 20 24 73 61 76 65   DSTOffset $save
6620: 0a 09 20 20 20 20 73 65 74 20 70 72 65 76 4c 65  ..    set prevLe
6630: 74 74 65 72 20 24 6c 65 74 74 65 72 0a 0a 09 20  tter $letter... 
6640: 20 20 20 23 20 52 65 63 6f 6e 76 65 72 74 20 74     # Reconvert t
6650: 68 65 20 27 75 6e 74 69 6c 27 20 74 69 6d 65 20  he 'until' time 
6660: 69 6e 20 74 68 65 20 63 75 72 72 65 6e 74 20 7a  in the current z
6670: 6f 6e 65 2e 0a 0a 09 20 20 20 20 69 66 20 7b 24  one....    if {$
6680: 75 6e 74 69 6c 20 6e 65 20 22 22 7d 20 7b 0a 09  until ne ""} {..
6690: 09 73 65 74 20 75 6e 74 69 6c 53 65 63 73 20 5b  .set untilSecs [
66a0: 63 6f 6e 76 65 72 74 54 69 6d 65 4f 66 44 61 79  convertTimeOfDay
66b0: 20 24 75 6e 74 69 6c 42 61 73 65 53 65 63 73 20   $untilBaseSecs 
66c0: 5c 0a 09 09 09 24 73 74 64 47 4d 54 4f 66 66 73  \....$stdGMTOffs
66d0: 65 74 20 24 44 53 54 4f 66 66 73 65 74 20 7b 2a  et $DSTOffset {*
66e0: 7d 24 75 6e 74 69 6c 54 69 6d 65 4f 66 44 61 79  }$untilTimeOfDay
66f0: 5d 0a 09 20 20 20 20 7d 0a 09 7d 0a 0a 09 23 20  ]..    }..}...# 
6700: 41 64 76 61 6e 63 65 20 74 6f 20 74 68 65 20 6e  Advance to the n
6710: 65 78 74 20 79 65 61 72 0a 0a 09 69 6e 63 72 20  ext year...incr 
6720: 79 65 61 72 0a 09 73 65 74 20 64 61 74 65 20 5b  year..set date [
6730: 3a 3a 74 63 6c 3a 3a 63 6c 6f 63 6b 3a 3a 47 65  ::tcl::clock::Ge
6740: 74 4a 75 6c 69 61 6e 44 61 79 46 72 6f 6d 45 72  tJulianDayFromEr
6750: 61 59 65 61 72 4d 6f 6e 74 68 44 61 79 20 5c 0a  aYearMonthDay \.
6760: 09 09 5b 64 69 63 74 20 63 72 65 61 74 65 20 65  ..[dict create e
6770: 72 61 20 43 45 20 79 65 61 72 20 24 79 65 61 72  ra CE year $year
6780: 20 6d 6f 6e 74 68 20 31 20 64 61 79 4f 66 4d 6f   month 1 dayOfMo
6790: 6e 74 68 20 31 5d 20 32 33 36 31 32 32 32 5d 0a  nth 1] 2361222].
67a0: 09 73 65 74 20 73 74 61 72 74 53 65 63 73 20 5b  .set startSecs [
67b0: 65 78 70 72 20 7b 0a 09 20 20 20 20 5b 64 69 63  expr {..    [dic
67c0: 74 20 67 65 74 20 24 64 61 74 65 20 6a 75 6c 69  t get $date juli
67d0: 61 6e 44 61 79 5d 20 2a 20 77 69 64 65 28 38 36  anDay] * wide(86
67e0: 34 30 30 29 20 2d 20 32 31 30 38 36 36 38 30 33  400) - 210866803
67f0: 32 30 30 0a 09 09 2d 20 24 73 74 64 47 4d 54 4f  200...- $stdGMTO
6800: 66 66 73 65 74 20 2d 20 24 44 53 54 4f 66 66 73  ffset - $DSTOffs
6810: 65 74 0a 09 7d 5d 0a 0a 09 23 20 47 65 74 20 72  et..}]...# Get r
6820: 75 6c 65 73 20 69 6e 20 65 66 66 65 63 74 20 69  ules in effect i
6830: 6e 20 74 68 65 20 6e 65 77 20 79 65 61 72 2e 0a  n the new year..
6840: 0a 09 6c 61 73 73 69 67 6e 20 5b 64 69 76 69 64  ..lassign [divid
6850: 65 52 75 6c 65 73 20 24 72 75 6c 65 53 65 74 20  eRules $ruleSet 
6860: 24 79 65 61 72 5d 20 63 75 72 72 65 6e 74 52 75  $year] currentRu
6870: 6c 65 73 20 6e 53 75 6e 73 65 74 52 75 6c 65 73  les nSunsetRules
6880: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 72 65 74 75  .    }..    retu
6890: 72 6e 20 5b 6c 69 73 74 20 24 73 74 64 47 4d 54  rn [list $stdGMT
68a0: 4f 66 66 73 65 74 20 24 44 53 54 4f 66 66 73 65  Offset $DSTOffse
68b0: 74 5d 0a 7d 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d  t].}..#---------
68c0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
68d0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
68e0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
68f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 0a  -------------.#.
6900: 23 20 64 69 76 69 64 65 52 75 6c 65 73 20 2d 2d  # divideRules --
6910: 0a 23 09 44 65 74 65 72 6d 69 6e 65 20 77 68 61  .#.Determine wha
6920: 74 20 44 61 79 6c 69 67 68 74 20 53 61 76 69 6e  t Daylight Savin
6930: 67 20 54 69 6d 65 20 72 75 6c 65 73 20 6d 61 79  g Time rules may
6940: 20 62 65 20 69 6e 20 65 66 66 65 63 74 20 69 6e   be in effect in
6950: 0a 23 09 61 20 67 69 76 65 6e 20 79 65 61 72 2e  .#.a given year.
6960: 0a 23 0a 23 20 50 61 72 61 6d 65 74 65 72 73 3a  .#.# Parameters:
6970: 0a 23 09 72 75 6c 65 53 65 74 20 2d 20 53 65 74  .#.ruleSet - Set
6980: 20 6f 66 20 72 75 6c 65 73 20 66 72 6f 6d 20 27   of rules from '
6990: 70 61 72 73 65 52 75 6c 65 27 0a 23 09 79 65 61  parseRule'.#.yea
69a0: 72 20 2d 20 59 65 61 72 20 74 6f 20 74 65 73 74  r - Year to test
69b0: 0a 23 0a 23 20 52 65 73 75 6c 74 73 3a 0a 23 09  .#.# Results:.#.
69c0: 52 65 74 75 72 6e 73 20 61 20 74 77 6f 20 65 6c  Returns a two el
69d0: 65 6d 65 6e 74 20 6c 69 73 74 20 63 6f 6d 70 72  ement list compr
69e0: 69 73 69 6e 67 20 74 68 65 20 73 75 62 73 65 74  ising the subset
69f0: 20 6f 66 20 27 72 75 6c 65 53 65 74 27 0a 23 09   of 'ruleSet'.#.
6a00: 74 68 61 74 20 69 73 20 69 6e 20 65 66 66 65 63  that is in effec
6a10: 74 20 69 6e 20 74 68 65 20 67 69 76 65 6e 20 79  t in the given y
6a20: 65 61 72 2c 20 61 6e 64 20 74 68 65 20 63 6f 75  ear, and the cou
6a30: 6e 74 20 6f 66 20 72 75 6c 65 73 0a 23 09 74 68  nt of rules.#.th
6a40: 61 74 20 65 78 70 69 72 65 20 69 6e 20 74 68 65  at expire in the
6a50: 20 66 75 74 75 72 65 20 28 61 73 20 6f 70 70 6f   future (as oppo
6a60: 73 65 64 20 74 6f 20 74 68 6f 73 65 20 74 68 61  sed to those tha
6a70: 74 20 65 78 70 69 72 65 20 69 6e 0a 23 09 74 68  t expire in.#.th
6a80: 65 20 70 61 73 74 20 6f 72 20 6e 6f 74 20 61 74  e past or not at
6a90: 20 61 6c 6c 29 2e 20 49 66 20 74 68 69 73 20 63   all). If this c
6aa0: 6f 75 6e 74 20 69 73 20 7a 65 72 6f 2c 20 74 68  ount is zero, th
6ab0: 65 20 72 75 6c 65 73 20 64 6f 0a 23 09 6e 6f 74  e rules do.#.not
6ac0: 20 63 68 61 6e 67 65 20 69 6e 20 66 75 74 75 72   change in futur
6ad0: 65 20 79 65 61 72 73 2e 0a 23 0a 23 20 53 69 64  e years..#.# Sid
6ae0: 65 20 65 66 66 65 63 74 73 3a 0a 23 09 4e 6f 6e  e effects:.#.Non
6af0: 65 2e 0a 23 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  e..#.#----------
6b00: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
6b10: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
6b20: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
6b30: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 0a 70 72  ------------..pr
6b40: 6f 63 20 64 69 76 69 64 65 52 75 6c 65 73 20 7b  oc divideRules {
6b50: 72 75 6c 65 53 65 74 20 79 65 61 72 7d 20 7b 0a  ruleSet year} {.
6b60: 20 20 20 20 76 61 72 69 61 62 6c 65 20 72 75 6c      variable rul
6b70: 65 73 0a 0a 20 20 20 20 73 65 74 20 63 75 72 72  es..    set curr
6b80: 65 6e 74 52 75 6c 65 73 20 7b 7d 0a 20 20 20 20  entRules {}.    
6b90: 73 65 74 20 6e 53 75 6e 73 65 74 52 75 6c 65 73  set nSunsetRules
6ba0: 20 30 0a 0a 20 20 20 20 66 6f 72 65 61 63 68 20   0..    foreach 
6bb0: 7b 0a 09 66 72 6f 6d 59 65 61 72 20 74 6f 59 65  {..fromYear toYe
6bc0: 61 72 20 79 65 61 72 54 79 70 65 20 6d 6f 6e 74  ar yearType mont
6bd0: 68 49 6e 20 64 61 79 53 70 65 63 4f 6e 20 74 69  hIn daySpecOn ti
6be0: 6d 65 41 74 20 73 61 76 65 20 6c 65 74 74 65 72  meAt save letter
6bf0: 0a 20 20 20 20 7d 20 24 72 75 6c 65 73 28 24 72  .    } $rules($r
6c00: 75 6c 65 53 65 74 29 20 7b 0a 09 69 66 20 7b 24  uleSet) {..if {$
6c10: 74 6f 59 65 61 72 20 6e 65 20 22 6d 61 78 69 6d  toYear ne "maxim
6c20: 75 6d 22 20 26 26 20 24 79 65 61 72 20 3e 20 24  um" && $year > $
6c30: 74 6f 59 65 61 72 7d 20 7b 0a 09 20 20 20 20 23  toYear} {..    #
6c40: 20 69 67 6e 6f 72 65 20 2d 20 72 75 6c 65 20 69   ignore - rule i
6c50: 73 20 69 6e 20 74 68 65 20 70 61 73 74 0a 09 7d  s in the past..}
6c60: 20 65 6c 73 65 20 7b 0a 09 20 20 20 20 69 66 20   else {..    if 
6c70: 7b 24 66 72 6f 6d 59 65 61 72 20 65 71 20 22 6d  {$fromYear eq "m
6c80: 69 6e 69 6d 75 6d 22 20 7c 7c 20 24 66 72 6f 6d  inimum" || $from
6c90: 59 65 61 72 20 3c 3d 20 24 79 65 61 72 7d 20 7b  Year <= $year} {
6ca0: 0a 09 09 6c 61 70 70 65 6e 64 20 63 75 72 72 65  ...lappend curre
6cb0: 6e 74 52 75 6c 65 73 20 24 66 72 6f 6d 59 65 61  ntRules $fromYea
6cc0: 72 20 24 74 6f 59 65 61 72 20 24 79 65 61 72 54  r $toYear $yearT
6cd0: 79 70 65 20 24 6d 6f 6e 74 68 49 6e 20 5c 0a 09  ype $monthIn \..
6ce0: 09 09 24 64 61 79 53 70 65 63 4f 6e 20 24 74 69  ..$daySpecOn $ti
6cf0: 6d 65 41 74 20 24 73 61 76 65 20 24 6c 65 74 74  meAt $save $lett
6d00: 65 72 0a 09 20 20 20 20 7d 0a 09 20 20 20 20 69  er..    }..    i
6d10: 66 20 7b 24 74 6f 59 65 61 72 20 6e 65 20 22 6d  f {$toYear ne "m
6d20: 61 78 69 6d 75 6d 22 7d 20 7b 0a 09 09 69 6e 63  aximum"} {...inc
6d30: 72 20 6e 53 75 6e 73 65 74 52 75 6c 65 73 0a 09  r nSunsetRules..
6d40: 20 20 20 20 7d 0a 09 7d 0a 20 20 20 20 7d 0a 0a      }..}.    }..
6d50: 20 20 20 20 72 65 74 75 72 6e 20 5b 6c 69 73 74      return [list
6d60: 20 24 63 75 72 72 65 6e 74 52 75 6c 65 73 20 24   $currentRules $
6d70: 6e 53 75 6e 73 65 74 52 75 6c 65 73 5d 0a 0a 7d  nSunsetRules]..}
6d80: 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ..#-------------
6d90: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
6da0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
6db0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
6dc0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 0a 23 20 66 69  ---------.#.# fi
6dd0: 6e 64 45 61 72 6c 69 65 73 74 52 75 6c 65 20 2d  ndEarliestRule -
6de0: 2d 0a 23 0a 23 09 46 69 6e 64 20 74 68 65 20 72  -.#.#.Find the r
6df0: 75 6c 65 20 69 6e 20 61 20 72 75 6c 65 20 73 65  ule in a rule se
6e00: 74 20 74 68 61 74 20 68 61 73 20 74 68 65 20 65  t that has the e
6e10: 61 72 6c 69 65 73 74 20 73 74 61 72 74 20 74 69  arliest start ti
6e20: 6d 65 2e 0a 23 0a 23 20 50 61 72 61 6d 65 74 65  me..#.# Paramete
6e30: 72 73 3a 0a 23 09 72 65 6d 61 69 6e 69 6e 67 52  rs:.#.remainingR
6e40: 75 6c 65 73 20 2d 2d 20 52 75 6c 65 73 20 74 6f  ules -- Rules to
6e50: 20 73 65 61 72 63 68 0a 23 09 79 65 61 72 20 2d   search.#.year -
6e60: 20 59 65 61 72 20 62 65 69 6e 67 20 70 72 6f 63   Year being proc
6e70: 65 73 73 65 64 2e 0a 23 09 73 74 64 47 4d 54 4f  essed..#.stdGMTO
6e80: 66 66 73 65 74 20 2d 20 43 75 72 72 65 6e 74 20  ffset - Current 
6e90: 6f 66 66 73 65 74 20 6f 66 20 73 74 61 6e 64 61  offset of standa
6ea0: 72 64 20 74 69 6d 65 20 66 72 6f 6d 20 47 4d 54  rd time from GMT
6eb0: 0a 23 09 44 53 54 4f 66 66 73 65 74 20 2d 20 43  .#.DSTOffset - C
6ec0: 75 72 72 65 6e 74 20 6f 66 66 73 65 74 20 6f 66  urrent offset of
6ed0: 20 64 61 79 6c 69 67 68 74 20 74 69 6d 65 20 66   daylight time f
6ee0: 72 6f 6d 20 73 74 61 6e 64 61 72 64 2c 0a 23 09  rom standard,.#.
6ef0: 09 20 20 20 20 69 66 20 64 61 79 6c 69 67 68 74  .    if daylight
6f00: 20 74 69 6d 65 20 69 73 20 69 6e 20 65 66 66 65   time is in effe
6f10: 63 74 2e 0a 23 0a 23 20 52 65 73 75 6c 74 73 3a  ct..#.# Results:
6f20: 0a 23 09 52 65 74 75 72 6e 73 20 74 68 65 20 69  .#.Returns the i
6f30: 6e 64 65 78 20 69 6e 20 72 65 6d 61 69 6e 69 6e  ndex in remainin
6f40: 67 52 75 6c 65 73 20 6f 66 20 74 68 65 20 6e 65  gRules of the ne
6f50: 78 74 20 72 75 6c 65 20 74 6f 0a 23 09 67 6f 20  xt rule to.#.go 
6f60: 69 6e 74 6f 20 65 66 66 65 63 74 2e 0a 23 0a 23  into effect..#.#
6f70: 20 53 69 64 65 20 65 66 66 65 63 74 73 3a 0a 23   Side effects:.#
6f80: 09 4e 6f 6e 65 2e 0a 23 0a 23 2d 2d 2d 2d 2d 2d  .None..#.#------
6f90: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
6fa0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
6fb0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
6fc0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
6fd0: 0a 0a 70 72 6f 63 20 66 69 6e 64 45 61 72 6c 69  ..proc findEarli
6fe0: 65 73 74 52 75 6c 65 20 7b 72 65 6d 61 69 6e 69  estRule {remaini
6ff0: 6e 67 52 75 6c 65 73 20 79 65 61 72 20 73 74 64  ngRules year std
7000: 47 4d 54 4f 66 66 73 65 74 20 44 53 54 4f 66 66  GMTOffset DSTOff
7010: 73 65 74 7d 20 7b 0a 20 20 20 20 73 65 74 20 65  set} {.    set e
7020: 61 72 6c 69 65 73 74 20 24 3a 3a 4d 41 58 57 49  arliest $::MAXWI
7030: 44 45 0a 20 20 20 20 73 65 74 20 69 20 30 0a 20  DE.    set i 0. 
7040: 20 20 20 66 6f 72 65 61 63 68 20 7b 0a 09 66 72     foreach {..fr
7050: 6f 6d 59 65 61 72 20 74 6f 59 65 61 72 20 79 65  omYear toYear ye
7060: 61 72 54 79 70 65 20 6d 6f 6e 74 68 49 6e 20 64  arType monthIn d
7070: 61 79 53 70 65 63 4f 6e 20 74 69 6d 65 41 74 20  aySpecOn timeAt 
7080: 73 61 76 65 20 6c 65 74 74 65 72 0a 20 20 20 20  save letter.    
7090: 7d 20 24 72 65 6d 61 69 6e 69 6e 67 52 75 6c 65  } $remainingRule
70a0: 73 20 7b 0a 09 6c 61 70 70 65 6e 64 20 64 61 79  s {..lappend day
70b0: 53 70 65 63 4f 6e 20 24 79 65 61 72 20 24 6d 6f  SpecOn $year $mo
70c0: 6e 74 68 49 6e 0a 09 73 65 74 20 64 61 79 49 6e  nthIn..set dayIn
70d0: 20 5b 65 76 61 6c 20 24 64 61 79 53 70 65 63 4f   [eval $daySpecO
70e0: 6e 5d 0a 09 73 65 74 20 73 65 63 73 20 5b 65 78  n]..set secs [ex
70f0: 70 72 20 7b 77 69 64 65 28 38 36 34 30 30 29 20  pr {wide(86400) 
7100: 2a 20 77 69 64 65 28 24 64 61 79 49 6e 29 20 2d  * wide($dayIn) -
7110: 20 32 31 30 38 36 36 38 30 33 32 30 30 7d 5d 0a   210866803200}].
7120: 09 73 65 74 20 73 65 63 73 20 5b 63 6f 6e 76 65  .set secs [conve
7130: 72 74 54 69 6d 65 4f 66 44 61 79 20 24 73 65 63  rtTimeOfDay $sec
7140: 73 20 5c 0a 09 09 24 73 74 64 47 4d 54 4f 66 66  s \...$stdGMTOff
7150: 73 65 74 20 24 44 53 54 4f 66 66 73 65 74 20 7b  set $DSTOffset {
7160: 2a 7d 24 74 69 6d 65 41 74 5d 0a 09 69 66 20 7b  *}$timeAt]..if {
7170: 24 73 65 63 73 20 3c 20 24 65 61 72 6c 69 65 73  $secs < $earlies
7180: 74 7d 20 7b 0a 09 20 20 20 20 73 65 74 20 65 61  t} {..    set ea
7190: 72 6c 69 65 73 74 20 24 73 65 63 73 0a 09 20 20  rliest $secs..  
71a0: 20 20 73 65 74 20 65 61 72 6c 69 65 73 74 49 64    set earliestId
71b0: 78 20 24 69 0a 09 7d 0a 09 69 6e 63 72 20 69 20  x $i..}..incr i 
71c0: 38 0a 20 20 20 20 7d 0a 0a 20 20 20 20 72 65 74  8.    }..    ret
71d0: 75 72 6e 20 5b 6c 69 73 74 20 24 65 61 72 6c 69  urn [list $earli
71e0: 65 73 74 20 24 65 61 72 6c 69 65 73 74 49 64 78  est $earliestIdx
71f0: 5d 0a 7d 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ].}..#----------
7200: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
7210: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
7220: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
7230: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 0a 23  ------------.#.#
7240: 20 63 6f 6e 76 65 72 74 4e 61 6d 65 50 61 74 74   convertNamePatt
7250: 65 72 6e 20 2d 2d 0a 23 0a 23 09 43 6f 6e 76 65  ern --.#.#.Conve
7260: 72 74 73 20 61 20 6e 61 6d 65 20 70 61 74 74 65  rts a name patte
7270: 72 6e 20 74 6f 20 74 68 65 20 6e 61 6d 65 20 6f  rn to the name o
7280: 66 20 74 68 65 20 74 69 6d 65 20 7a 6f 6e 65 2e  f the time zone.
7290: 0a 23 0a 23 20 50 61 72 61 6d 65 74 65 72 73 3a  .#.# Parameters:
72a0: 0a 23 09 70 61 74 74 65 72 6e 20 2d 20 50 61 74  .#.pattern - Pat
72b0: 74 68 65 72 6e 20 74 6f 20 63 6f 6e 76 65 72 74  thern to convert
72c0: 0a 23 09 66 6c 61 67 20 2d 20 44 61 79 6c 69 67  .#.flag - Daylig
72d0: 68 74 20 54 69 6d 65 20 66 6c 61 67 2e 20 41 6e  ht Time flag. An
72e0: 20 65 6d 70 74 79 20 73 74 72 69 6e 67 20 64 65   empty string de
72f0: 6e 6f 74 65 73 20 53 74 61 6e 64 61 72 64 0a 23  notes Standard.#
7300: 09 20 20 20 20 20 20 20 54 69 6d 65 2c 20 61 6e  .       Time, an
7310: 79 74 68 69 6e 67 20 65 6c 73 65 20 69 73 20 44  ything else is D
7320: 61 79 6c 69 67 68 74 20 54 69 6d 65 2e 0a 23 0a  aylight Time..#.
7330: 23 20 52 65 73 75 6c 74 73 3b 0a 23 09 52 65 74  # Results;.#.Ret
7340: 75 72 6e 73 20 74 68 65 20 6e 61 6d 65 20 6f 66  urns the name of
7350: 20 74 68 65 20 74 69 6d 65 20 7a 6f 6e 65 2e 0a   the time zone..
7360: 23 0a 23 20 53 69 64 65 20 65 66 66 65 63 74 73  #.# Side effects
7370: 3a 0a 23 09 4e 6f 6e 65 2e 0a 23 0a 23 2d 2d 2d  :.#.None..#.#---
7380: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
7390: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
73a0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
73b0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
73c0: 2d 2d 2d 0a 0a 70 72 6f 63 20 63 6f 6e 76 65 72  ---..proc conver
73d0: 74 4e 61 6d 65 50 61 74 74 65 72 6e 20 7b 70 61  tNamePattern {pa
73e0: 74 74 65 72 6e 20 66 6c 61 67 7d 20 7b 0a 20 20  ttern flag} {.  
73f0: 20 20 69 66 20 7b 5b 72 65 67 65 78 70 20 7b 28    if {[regexp {(
7400: 2e 2a 29 2f 28 2e 2a 29 7d 20 24 70 61 74 74 65  .*)/(.*)} $patte
7410: 72 6e 20 2d 3e 20 73 74 61 6e 64 61 72 64 20 64  rn -> standard d
7420: 61 79 6c 69 67 68 74 5d 7d 20 7b 0a 09 69 66 20  aylight]} {..if 
7430: 7b 24 66 6c 61 67 20 6e 65 20 22 22 7d 20 7b 0a  {$flag ne ""} {.
7440: 09 20 20 20 20 73 65 74 20 70 61 74 74 65 72 6e  .    set pattern
7450: 20 24 64 61 79 6c 69 67 68 74 0a 09 7d 20 65 6c   $daylight..} el
7460: 73 65 20 7b 0a 09 20 20 20 20 73 65 74 20 70 61  se {..    set pa
7470: 74 74 65 72 6e 20 24 73 74 61 6e 64 61 72 64 0a  ttern $standard.
7480: 09 7d 0a 20 20 20 20 7d 0a 20 20 20 20 72 65 74  .}.    }.    ret
7490: 75 72 6e 20 5b 73 74 72 69 6e 67 20 6d 61 70 20  urn [string map 
74a0: 5b 6c 69 73 74 20 25 73 20 24 66 6c 61 67 5d 20  [list %s $flag] 
74b0: 24 70 61 74 74 65 72 6e 5d 0a 7d 0a 0a 23 2d 2d  $pattern].}..#--
74c0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
74d0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
74e0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
74f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
7500: 2d 2d 2d 2d 0a 23 0a 23 20 63 6f 6e 76 65 72 74  ----.#.# convert
7510: 54 69 6d 65 4f 66 44 61 79 20 2d 2d 0a 23 0a 23  TimeOfDay --.#.#
7520: 09 54 61 6b 65 73 20 61 20 74 69 6d 65 20 6f 66  .Takes a time of
7530: 20 64 61 79 20 73 70 65 63 69 66 69 65 72 20 66   day specifier f
7540: 72 6f 6d 20 27 70 61 72 73 65 41 74 27 20 61 6e  rom 'parseAt' an
7550: 64 20 63 6f 6e 76 65 72 74 73 0a 23 09 74 6f 20  d converts.#.to 
7560: 73 65 63 6f 6e 64 73 20 66 72 6f 6d 20 74 68 65  seconds from the
7570: 20 45 70 6f 63 68 2c 0a 23 0a 23 20 50 61 72 61   Epoch,.#.# Para
7580: 6d 65 74 65 72 73 3a 0a 23 09 73 65 63 6f 6e 64  meters:.#.second
7590: 73 20 2d 2d 20 54 69 6d 65 20 61 74 20 77 68 69  s -- Time at whi
75a0: 63 68 20 74 68 65 20 47 4d 54 20 64 61 79 20 73  ch the GMT day s
75b0: 74 61 72 74 73 2c 20 69 6e 20 73 65 63 6f 6e 64  tarts, in second
75c0: 73 0a 23 09 09 20 20 20 66 72 6f 6d 20 74 68 65  s.#..   from the
75d0: 20 50 6f 73 69 78 20 65 70 6f 63 68 0a 23 09 73   Posix epoch.#.s
75e0: 74 64 47 4d 54 4f 66 66 73 65 74 20 2d 20 4f 66  tdGMTOffset - Of
75f0: 66 73 65 74 20 6f 66 20 53 74 61 6e 64 61 72 64  fset of Standard
7600: 20 54 69 6d 65 20 66 72 6f 6d 20 47 72 65 65 6e   Time from Green
7610: 77 69 63 68 0a 23 09 44 53 54 4f 66 66 73 65 74  wich.#.DSTOffset
7620: 20 2d 20 4f 66 66 73 65 74 20 6f 66 20 44 61 79   - Offset of Day
7630: 6c 69 67 68 74 20 54 69 6d 65 20 66 72 6f 6d 20  light Time from 
7640: 73 74 61 6e 64 61 72 64 2e 0a 23 09 74 69 6d 65  standard..#.time
7650: 4f 66 44 61 79 20 2d 20 54 69 6d 65 20 6f 66 20  OfDay - Time of 
7660: 64 61 79 20 74 6f 20 63 6f 6e 76 65 72 74 2c 20  day to convert, 
7670: 69 6e 20 73 65 63 6f 6e 64 73 20 66 72 6f 6d 20  in seconds from 
7680: 6d 69 64 6e 69 67 68 74 0a 23 09 66 6c 61 67 20  midnight.#.flag 
7690: 2d 20 46 6c 61 67 20 69 6e 64 69 63 61 74 69 6e  - Flag indicatin
76a0: 67 20 77 68 65 74 68 65 72 20 74 68 65 20 74 69  g whether the ti
76b0: 6d 65 20 69 73 20 47 72 65 65 6e 77 69 63 68 2c  me is Greenwich,
76c0: 20 53 74 61 6e 64 61 72 64 0a 23 09 20 20 20 20   Standard.#.    
76d0: 20 20 20 6f 72 20 77 61 6c 6c 2d 63 6c 6f 63 6b     or wall-clock
76e0: 2e 20 28 67 2c 20 73 2c 20 6f 72 20 77 29 0a 23  . (g, s, or w).#
76f0: 0a 23 20 52 65 73 75 6c 74 73 3a 0a 23 09 52 65  .# Results:.#.Re
7700: 74 75 72 6e 73 20 74 68 65 20 74 69 6d 65 20 6f  turns the time o
7710: 66 20 64 61 79 20 69 6e 20 73 65 63 6f 6e 64 73  f day in seconds
7720: 20 66 72 6f 6d 20 74 68 65 20 50 6f 73 69 78 20   from the Posix 
7730: 65 70 6f 63 68 2e 0a 23 0a 23 20 53 69 64 65 20  epoch..#.# Side 
7740: 65 66 66 65 63 74 73 3a 0a 23 09 4e 6f 6e 65 2e  effects:.#.None.
7750: 0a 23 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  .#.#------------
7760: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
7770: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
7780: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
7790: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 0a 70 72 6f 63  ----------..proc
77a0: 20 63 6f 6e 76 65 72 74 54 69 6d 65 4f 66 44 61   convertTimeOfDa
77b0: 79 20 7b 73 65 63 6f 6e 64 73 20 73 74 64 47 4d  y {seconds stdGM
77c0: 54 4f 66 66 73 65 74 20 44 53 54 4f 66 66 73 65  TOffset DSTOffse
77d0: 74 20 74 69 6d 65 4f 66 44 61 79 20 66 6c 61 67  t timeOfDay flag
77e0: 7d 20 7b 0a 20 20 20 20 69 6e 63 72 20 73 65 63  } {.    incr sec
77f0: 6f 6e 64 73 20 24 74 69 6d 65 4f 66 44 61 79 0a  onds $timeOfDay.
7800: 20 20 20 20 73 77 69 74 63 68 20 2d 65 78 61 63      switch -exac
7810: 74 20 24 66 6c 61 67 20 7b 0a 09 67 20 2d 20 75  t $flag {..g - u
7820: 20 2d 20 7a 20 7b 0a 09 7d 0a 09 77 20 7b 0a 09   - z {..}..w {..
7830: 20 20 20 20 69 6e 63 72 20 73 65 63 6f 6e 64 73      incr seconds
7840: 20 5b 65 78 70 72 20 7b 2d 24 73 74 64 47 4d 54   [expr {-$stdGMT
7850: 4f 66 66 73 65 74 7d 5d 0a 09 20 20 20 20 69 6e  Offset}]..    in
7860: 63 72 20 73 65 63 6f 6e 64 73 20 5b 65 78 70 72  cr seconds [expr
7870: 20 7b 2d 24 44 53 54 4f 66 66 73 65 74 7d 5d 0a   {-$DSTOffset}].
7880: 09 7d 0a 09 73 20 7b 0a 09 20 20 20 20 69 6e 63  .}..s {..    inc
7890: 72 20 73 65 63 6f 6e 64 73 20 5b 65 78 70 72 20  r seconds [expr 
78a0: 7b 2d 24 73 74 64 47 4d 54 4f 66 66 73 65 74 7d  {-$stdGMTOffset}
78b0: 5d 0a 09 7d 0a 20 20 20 20 7d 0a 20 20 20 20 72  ]..}.    }.    r
78c0: 65 74 75 72 6e 20 24 73 65 63 6f 6e 64 73 0a 7d  eturn $seconds.}
78d0: 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ..#-------------
78e0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
78f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
7900: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
7910: 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 0a 23 20 70 72  ---------.#.# pr
7920: 6f 63 65 73 73 54 69 6d 65 5a 6f 6e 65 20 2d 2d  ocessTimeZone --
7930: 0a 23 0a 23 09 47 65 6e 65 72 61 74 65 20 74 68  .#.#.Generate th
7940: 65 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 61 62  e information ab
7950: 6f 75 74 20 61 6c 6c 20 74 69 6d 65 20 74 72 61  out all time tra
7960: 6e 73 69 74 69 6f 6e 73 20 69 6e 20 61 0a 23 09  nsitions in a.#.
7970: 74 69 6d 65 20 7a 6f 6e 65 2e 0a 23 0a 23 20 50  time zone..#.# P
7980: 61 72 61 6d 65 74 65 72 73 3a 0a 23 09 7a 6f 6e  arameters:.#.zon
7990: 65 4e 61 6d 65 20 2d 20 4e 61 6d 65 20 6f 66 20  eName - Name of 
79a0: 74 68 65 20 74 69 6d 65 20 7a 6f 6e 65 0a 23 09  the time zone.#.
79b0: 7a 6f 6e 65 44 61 74 61 20 2d 20 4c 69 73 74 20  zoneData - List 
79c0: 63 6f 6e 74 61 69 6e 69 6e 67 20 74 68 65 20 72  containing the r
79d0: 6f 77 73 20 64 65 73 63 72 69 62 69 6e 67 20 74  ows describing t
79e0: 68 65 20 74 69 6d 65 20 7a 6f 6e 65 2c 0a 23 09  he time zone,.#.
79f0: 09 20 20 20 6f 62 74 61 69 6e 65 64 20 66 72 6f  .   obtained fro
7a00: 6d 20 27 70 61 72 73 65 5a 6f 6e 65 2e 0a 23 0a  m 'parseZone..#.
7a10: 23 20 52 65 73 75 6c 74 73 3a 0a 23 09 52 65 74  # Results:.#.Ret
7a20: 75 72 6e 73 20 61 20 6c 69 73 74 20 6f 66 20 72  urns a list of r
7a30: 6f 77 73 2e 09 20 45 61 63 68 20 72 6f 77 20 63  ows.. Each row c
7a40: 6f 6e 73 69 73 74 73 20 6f 66 20 61 20 74 69 6d  onsists of a tim
7a50: 65 20 69 6e 0a 23 09 73 65 63 6f 6e 64 73 20 66  e in.#.seconds f
7a60: 72 6f 6d 20 74 68 65 20 50 6f 73 69 78 20 65 70  rom the Posix ep
7a70: 6f 63 68 2c 20 61 6e 20 6f 66 66 73 65 74 20 66  och, an offset f
7a80: 72 6f 6d 20 47 4d 54 20 74 6f 20 6c 6f 63 61 6c  rom GMT to local
7a90: 0a 23 09 74 68 61 74 20 62 65 67 69 6e 73 20 61  .#.that begins a
7aa0: 74 20 74 68 61 74 20 74 69 6d 65 2c 20 61 20 66  t that time, a f
7ab0: 6c 61 67 20 69 6e 64 69 63 61 74 69 6e 67 20 77  lag indicating w
7ac0: 68 65 74 68 65 72 20 44 53 54 0a 23 09 69 73 20  hether DST.#.is 
7ad0: 69 6e 20 65 66 66 65 63 74 20 61 66 74 65 72 20  in effect after 
7ae0: 74 68 61 74 20 74 69 6d 65 2c 20 61 6e 64 20 74  that time, and t
7af0: 68 65 20 70 72 69 6e 74 61 62 6c 65 20 6e 61 6d  he printable nam
7b00: 65 20 6f 66 20 74 68 65 0a 23 09 74 69 6d 65 7a  e of the.#.timez
7b10: 6f 6e 65 20 74 68 61 74 20 67 6f 65 73 20 69 6e  one that goes in
7b20: 74 6f 20 65 66 66 65 63 74 20 61 74 20 74 68 61  to effect at tha
7b30: 74 20 74 69 6d 65 2e 0a 23 0a 23 20 53 69 64 65  t time..#.# Side
7b40: 20 65 66 66 65 63 74 73 3a 0a 23 09 4e 6f 6e 65   effects:.#.None
7b50: 2e 0a 23 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ..#.#-----------
7b60: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
7b70: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
7b80: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
7b90: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 0a 70 72 6f  -----------..pro
7ba0: 63 20 70 72 6f 63 65 73 73 54 69 6d 65 5a 6f 6e  c processTimeZon
7bb0: 65 20 7b 7a 6f 6e 65 4e 61 6d 65 20 7a 6f 6e 65  e {zoneName zone
7bc0: 44 61 74 61 7d 20 7b 0a 20 20 20 20 73 65 74 20  Data} {.    set 
7bd0: 70 6f 69 6e 74 73 20 7b 7d 0a 20 20 20 20 73 65  points {}.    se
7be0: 74 20 69 20 30 0a 20 20 20 20 66 6f 72 65 61 63  t i 0.    foreac
7bf0: 68 20 7b 73 74 61 72 74 54 69 6d 65 20 6e 65 78  h {startTime nex
7c00: 74 47 4d 54 4f 66 66 73 65 74 20 64 73 74 52 75  tGMTOffset dstRu
7c10: 6c 65 20 6e 61 6d 65 50 61 74 74 65 72 6e 7d 20  le namePattern} 
7c20: 24 7a 6f 6e 65 44 61 74 61 20 7b 0a 09 69 6e 63  $zoneData {..inc
7c30: 72 20 69 20 34 0a 09 73 65 74 20 75 6e 74 69 6c  r i 4..set until
7c40: 20 5b 6c 69 6e 64 65 78 20 24 7a 6f 6e 65 44 61   [lindex $zoneDa
7c50: 74 61 20 24 69 5d 0a 09 69 66 20 7b 21 5b 69 6e  ta $i]..if {![in
7c60: 66 6f 20 65 78 69 73 74 73 20 73 74 64 47 4d 54  fo exists stdGMT
7c70: 4f 66 66 73 65 74 5d 7d 20 7b 0a 09 20 20 20 20  Offset]} {..    
7c80: 73 65 74 20 73 74 64 47 4d 54 4f 66 66 73 65 74  set stdGMTOffset
7c90: 20 24 6e 65 78 74 47 4d 54 4f 66 66 73 65 74 0a   $nextGMTOffset.
7ca0: 09 7d 0a 09 69 66 20 7b 21 5b 69 6e 66 6f 20 65  .}..if {![info e
7cb0: 78 69 73 74 73 20 44 53 54 4f 66 66 73 65 74 5d  xists DSTOffset]
7cc0: 7d 20 7b 0a 09 20 20 20 20 73 65 74 20 44 53 54  } {..    set DST
7cd0: 4f 66 66 73 65 74 20 30 0a 09 7d 0a 09 69 66 20  Offset 0..}..if 
7ce0: 7b 24 73 74 61 72 74 54 69 6d 65 20 65 71 20 22  {$startTime eq "
7cf0: 6d 69 6e 69 6d 75 6d 22 7d 20 7b 0a 09 20 20 20  minimum"} {..   
7d00: 20 73 65 74 20 73 65 63 73 20 24 3a 3a 4d 49 4e   set secs $::MIN
7d10: 57 49 44 45 0a 09 20 20 20 20 73 65 74 20 79 65  WIDE..    set ye
7d20: 61 72 20 30 0a 09 7d 20 65 6c 73 65 20 7b 0a 09  ar 0..} else {..
7d30: 20 20 20 20 6c 61 73 73 69 67 6e 20 24 73 74 61      lassign $sta
7d40: 72 74 54 69 6d 65 20 79 65 61 72 20 6d 6f 6e 74  rtTime year mont
7d50: 68 20 64 61 79 52 75 6c 65 20 74 69 6d 65 4f 66  h dayRule timeOf
7d60: 44 61 79 0a 09 20 20 20 20 6c 61 70 70 65 6e 64  Day..    lappend
7d70: 20 64 61 79 52 75 6c 65 20 24 79 65 61 72 20 24   dayRule $year $
7d80: 6d 6f 6e 74 68 0a 09 20 20 20 20 73 65 74 20 73  month..    set s
7d90: 74 61 72 74 44 61 79 20 5b 65 76 61 6c 20 24 64  tartDay [eval $d
7da0: 61 79 52 75 6c 65 5d 0a 09 20 20 20 20 73 65 74  ayRule]..    set
7db0: 20 73 65 63 73 20 5b 65 78 70 72 20 7b 77 69 64   secs [expr {wid
7dc0: 65 28 38 36 34 30 30 29 20 2a 20 77 69 64 65 28  e(86400) * wide(
7dd0: 24 73 74 61 72 74 44 61 79 29 20 2d 32 31 30 38  $startDay) -2108
7de0: 36 36 38 30 33 32 30 30 7d 5d 0a 09 20 20 20 20  66803200}]..    
7df0: 73 65 74 20 73 65 63 73 20 5b 63 6f 6e 76 65 72  set secs [conver
7e00: 74 54 69 6d 65 4f 66 44 61 79 20 24 73 65 63 73  tTimeOfDay $secs
7e10: 20 5c 0a 09 09 20 20 20 20 24 73 74 64 47 4d 54   \...    $stdGMT
7e20: 4f 66 66 73 65 74 20 24 44 53 54 4f 66 66 73 65  Offset $DSTOffse
7e30: 74 20 7b 2a 7d 24 74 69 6d 65 4f 66 44 61 79 5d  t {*}$timeOfDay]
7e40: 0a 09 7d 0a 09 6c 61 70 70 65 6e 64 20 64 73 74  ..}..lappend dst
7e50: 52 75 6c 65 20 5c 0a 09 09 24 79 65 61 72 20 24  Rule \...$year $
7e60: 73 65 63 73 20 24 73 74 64 47 4d 54 4f 66 66 73  secs $stdGMTOffs
7e70: 65 74 20 24 44 53 54 4f 66 66 73 65 74 20 24 6e  et $DSTOffset $n
7e80: 65 78 74 47 4d 54 4f 66 66 73 65 74 20 5c 0a 09  extGMTOffset \..
7e90: 09 24 6e 61 6d 65 50 61 74 74 65 72 6e 20 24 75  .$namePattern $u
7ea0: 6e 74 69 6c 20 70 6f 69 6e 74 73 0a 09 6c 61 73  ntil points..las
7eb0: 73 69 67 6e 20 5b 65 76 61 6c 20 24 64 73 74 52  sign [eval $dstR
7ec0: 75 6c 65 5d 20 73 74 64 47 4d 54 4f 66 66 73 65  ule] stdGMTOffse
7ed0: 74 20 44 53 54 4f 66 66 73 65 74 0a 20 20 20 20  t DSTOffset.    
7ee0: 7d 0a 20 20 20 20 72 65 74 75 72 6e 20 24 70 6f  }.    return $po
7ef0: 69 6e 74 73 0a 7d 0a 0a 23 2d 2d 2d 2d 2d 2d 2d  ints.}..#-------
7f00: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
7f10: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
7f20: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
7f30: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a  ---------------.
7f40: 23 0a 23 20 77 72 69 74 65 5a 6f 6e 65 73 20 2d  #.# writeZones -
7f50: 2d 0a 23 0a 23 09 57 72 69 74 65 73 20 61 6c 6c  -.#.#.Writes all
7f60: 20 74 68 65 20 74 69 6d 65 20 7a 6f 6e 65 20 69   the time zone i
7f70: 6e 66 6f 72 6d 61 74 69 6f 6e 20 66 69 6c 65 73  nformation files
7f80: 2e 0a 23 0a 23 20 50 61 72 61 6d 65 74 65 72 73  ..#.# Parameters
7f90: 3a 0a 23 09 6f 75 74 44 69 72 20 2d 20 44 69 72  :.#.outDir - Dir
7fa0: 65 63 74 6f 72 79 20 69 6e 20 77 68 69 63 68 20  ectory in which 
7fb0: 74 6f 20 73 74 6f 72 65 20 74 68 65 20 66 69 6c  to store the fil
7fc0: 65 73 2e 0a 23 0a 23 20 52 65 73 75 6c 74 73 3a  es..#.# Results:
7fd0: 0a 23 09 4e 6f 6e 65 2e 0a 23 0a 23 20 53 69 64  .#.None..#.# Sid
7fe0: 65 20 65 66 66 65 63 74 73 3a 0a 23 09 57 72 69  e effects:.#.Wri
7ff0: 74 65 73 20 74 68 65 20 74 69 6d 65 20 7a 6f 6e  tes the time zon
8000: 65 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 66 69  e information fi
8010: 6c 65 73 3b 20 74 72 61 63 65 73 20 77 68 61 74  les; traces what
8020: 27 73 20 68 61 70 70 65 6e 69 6e 67 0a 23 09 6f  's happening.#.o
8030: 6e 20 74 68 65 20 73 74 61 6e 64 61 72 64 20 6f  n the standard o
8040: 75 74 70 75 74 2e 0a 23 0a 23 2d 2d 2d 2d 2d 2d  utput..#.#------
8050: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
8060: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
8070: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
8080: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
8090: 0a 0a 70 72 6f 63 20 77 72 69 74 65 5a 6f 6e 65  ..proc writeZone
80a0: 73 20 7b 6f 75 74 44 69 72 7d 20 7b 0a 20 20 20  s {outDir} {.   
80b0: 20 76 61 72 69 61 62 6c 65 20 7a 6f 6e 65 73 0a   variable zones.
80c0: 0a 20 20 20 20 23 20 57 61 6c 6b 20 74 68 65 20  .    # Walk the 
80d0: 7a 6f 6e 65 73 0a 0a 20 20 20 20 66 6f 72 65 61  zones..    forea
80e0: 63 68 20 7a 6f 6e 65 4e 61 6d 65 20 5b 6c 73 6f  ch zoneName [lso
80f0: 72 74 20 2d 64 69 63 74 69 6f 6e 61 72 79 20 5b  rt -dictionary [
8100: 61 72 72 61 79 20 6e 61 6d 65 73 20 7a 6f 6e 65  array names zone
8110: 73 5d 5d 20 7b 0a 09 70 75 74 73 20 22 63 61 6c  s]] {..puts "cal
8120: 63 75 6c 61 74 69 6e 67 3a 20 24 7a 6f 6e 65 4e  culating: $zoneN
8130: 61 6d 65 22 0a 09 73 65 74 20 66 69 6c 65 4e 61  ame"..set fileNa
8140: 6d 65 20 5b 65 76 61 6c 20 5b 6c 69 73 74 20 66  me [eval [list f
8150: 69 6c 65 20 6a 6f 69 6e 20 24 6f 75 74 44 69 72  ile join $outDir
8160: 5d 20 5b 66 69 6c 65 20 73 70 6c 69 74 20 24 7a  ] [file split $z
8170: 6f 6e 65 4e 61 6d 65 5d 5d 0a 0a 09 23 20 43 72  oneName]]...# Cr
8180: 65 61 74 65 20 64 69 72 65 63 74 6f 72 69 65 73  eate directories
8190: 20 61 73 20 6e 65 65 64 65 64 0a 0a 09 73 65 74   as needed...set
81a0: 20 64 69 72 4e 61 6d 65 20 5b 66 69 6c 65 20 64   dirName [file d
81b0: 69 72 6e 61 6d 65 20 24 66 69 6c 65 4e 61 6d 65  irname $fileName
81c0: 5d 0a 09 69 66 20 7b 21 5b 66 69 6c 65 20 65 78  ]..if {![file ex
81d0: 69 73 74 73 20 24 64 69 72 4e 61 6d 65 5d 7d 20  ists $dirName]} 
81e0: 7b 0a 09 20 20 20 20 70 75 74 73 20 22 63 72 65  {..    puts "cre
81f0: 61 74 69 6e 67 20 64 69 72 65 63 74 6f 72 79 3a  ating directory:
8200: 20 24 64 69 72 4e 61 6d 65 22 0a 09 20 20 20 20   $dirName"..    
8210: 66 69 6c 65 20 6d 6b 64 69 72 20 24 64 69 72 4e  file mkdir $dirN
8220: 61 6d 65 0a 09 7d 0a 0a 09 23 20 47 65 6e 65 72  ame..}...# Gener
8230: 61 74 65 20 64 61 74 61 20 66 6f 72 20 61 20 7a  ate data for a z
8240: 6f 6e 65 0a 0a 09 73 65 74 20 64 61 74 61 20 22  one...set data "
8250: 22 0a 09 73 65 74 20 74 7a 6d 61 70 70 65 64 20  "..set tzmapped 
8260: 7b 7d 0a 09 66 6f 72 65 61 63 68 20 7b 0a 09 20  {}..foreach {.. 
8270: 20 20 20 74 69 6d 65 20 6f 66 66 73 65 74 20 64     time offset d
8280: 73 74 20 6e 61 6d 65 0a 09 7d 20 5b 70 72 6f 63  st name..} [proc
8290: 65 73 73 54 69 6d 65 5a 6f 6e 65 20 24 7a 6f 6e  essTimeZone $zon
82a0: 65 4e 61 6d 65 20 24 7a 6f 6e 65 73 28 24 7a 6f  eName $zones($zo
82b0: 6e 65 4e 61 6d 65 29 5d 20 7b 0a 09 20 20 20 20  neName)] {..    
82c0: 69 66 20 7b 24 6e 61 6d 65 20 65 71 20 22 25 7a  if {$name eq "%z
82d0: 22 7d 20 7b 0a 09 09 23 20 6d 61 70 20 25 7a 20  "} {...# map %z 
82e0: 74 6f 20 70 75 72 65 20 6f 66 66 73 65 74 20 7a  to pure offset z
82f0: 6f 6e 65 20 28 65 2e 20 67 2e 20 6f 66 66 73 65  one (e. g. offse
8300: 74 20 2d 37 32 30 30 20 2d 3e 20 2d 30 32 30 30  t -7200 -> -0200
8310: 29 3a 0a 09 09 73 65 74 20 6f 66 66 6d 69 6e 20  ):...set offmin 
8320: 5b 65 78 70 72 20 7b 61 62 73 28 24 6f 66 66 73  [expr {abs($offs
8330: 65 74 29 20 2f 20 36 30 7d 5d 0a 09 09 73 65 74  et) / 60}]...set
8340: 20 6e 61 6d 65 20 5b 66 6f 72 6d 61 74 20 22 25   name [format "%
8350: 2b 30 33 64 25 30 32 64 22 20 5b 65 78 70 72 20  +03d%02d" [expr 
8360: 7b 0a 09 09 09 09 28 24 6f 66 66 73 65 74 20 3c  {.....($offset <
8370: 20 30 20 3f 20 2d 31 20 3a 20 31 29 20 2a 20 28   0 ? -1 : 1) * (
8380: 24 6f 66 66 6d 69 6e 20 2f 20 36 30 29 0a 09 09  $offmin / 60)...
8390: 09 20 20 20 20 7d 5d 20 5b 65 78 70 72 20 7b 0a  .    }] [expr {.
83a0: 09 09 09 09 24 6f 66 66 6d 69 6e 20 25 20 36 30  ....$offmin % 60
83b0: 0a 09 09 09 20 20 20 20 7d 5d 0a 09 09 09 5d 0a  ....    }]....].
83c0: 09 09 69 66 20 7b 21 5b 64 69 63 74 20 65 78 69  ..if {![dict exi
83d0: 73 74 73 20 24 74 7a 6d 61 70 70 65 64 20 24 6f  sts $tzmapped $o
83e0: 66 66 73 65 74 5d 7d 20 7b 20 23 20 6f 75 74 70  ffset]} { # outp
83f0: 75 74 20 6f 6e 63 65 20 70 65 72 20 6f 66 66 73  ut once per offs
8400: 0a 09 09 20 20 20 20 70 75 74 73 20 22 5c 74 6d  ...    puts "\tm
8410: 61 70 20 25 7a 20 28 24 6f 66 66 73 65 74 29 20  ap %z ($offset) 
8420: 2d 3e 20 24 6e 61 6d 65 22 0a 09 09 20 20 20 20  -> $name"...    
8430: 64 69 63 74 20 73 65 74 20 74 7a 6d 61 70 70 65  dict set tzmappe
8440: 64 20 24 6f 66 66 73 65 74 20 24 6e 61 6d 65 0a  d $offset $name.
8450: 09 09 7d 0a 09 20 20 20 20 7d 0a 09 20 20 20 20  ..}..    }..    
8460: 61 70 70 65 6e 64 20 64 61 74 61 20 22 5c 6e 20  append data "\n 
8470: 20 20 20 22 20 5b 6c 69 73 74 20 5b 6c 69 73 74     " [list [list
8480: 20 24 74 69 6d 65 20 24 6f 66 66 73 65 74 20 24   $time $offset $
8490: 64 73 74 20 24 6e 61 6d 65 5d 5d 0a 09 7d 0a 09  dst $name]]..}..
84a0: 61 70 70 65 6e 64 20 64 61 74 61 20 5c 6e 0a 0a  append data \n..
84b0: 09 23 20 57 72 69 74 65 20 74 68 65 20 64 61 74  .# Write the dat
84c0: 61 20 74 6f 20 74 68 65 20 69 6e 66 6f 72 6d 61  a to the informa
84d0: 74 69 6f 6e 20 66 69 6c 65 0a 0a 09 73 65 74 20  tion file...set 
84e0: 66 20 5b 6f 70 65 6e 20 24 66 69 6c 65 4e 61 6d  f [open $fileNam
84f0: 65 20 77 5d 0a 09 66 63 6f 6e 66 69 67 75 72 65  e w]..fconfigure
8500: 20 24 66 20 2d 74 72 61 6e 73 6c 61 74 69 6f 6e   $f -translation
8510: 20 6c 66 20 2d 65 6e 63 6f 64 69 6e 67 20 75 74   lf -encoding ut
8520: 66 2d 38 0a 09 70 75 74 73 20 24 66 20 22 5c 23  f-8..puts $f "\#
8530: 20 63 72 65 61 74 65 64 20 62 79 20 24 3a 3a 61   created by $::a
8540: 72 67 76 30 20 2d 20 64 6f 20 6e 6f 74 20 65 64  rgv0 - do not ed
8550: 69 74 22 0a 09 70 75 74 73 20 24 66 20 22 22 0a  it"..puts $f "".
8560: 09 70 75 74 73 20 24 66 20 5b 6c 69 73 74 20 73  .puts $f [list s
8570: 65 74 20 54 5a 44 61 74 61 28 3a 24 7a 6f 6e 65  et TZData(:$zone
8580: 4e 61 6d 65 29 20 24 64 61 74 61 5d 0a 09 63 6c  Name) $data]..cl
8590: 6f 73 65 20 24 66 0a 20 20 20 20 7d 0a 0a 20 20  ose $f.    }..  
85a0: 20 20 72 65 74 75 72 6e 0a 7d 0a 0a 23 2d 2d 2d    return.}..#---
85b0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
85c0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
85d0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
85e0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
85f0: 2d 2d 2d 0a 23 0a 23 20 77 72 69 74 65 4c 69 6e  ---.#.# writeLin
8600: 6b 73 20 2d 2d 0a 23 0a 23 09 57 72 69 74 65 20  ks --.#.#.Write 
8610: 66 69 6c 65 73 20 64 65 73 63 72 69 62 69 6e 67  files describing
8620: 20 74 69 6d 65 20 7a 6f 6e 65 20 73 79 6e 6f 6e   time zone synon
8630: 79 6d 73 20 28 74 68 65 20 4c 69 6e 6b 20 64 69  yms (the Link di
8640: 72 65 63 74 69 76 65 73 0a 23 09 66 72 6f 6d 20  rectives.#.from 
8650: 74 68 65 20 4f 6c 73 6f 6e 20 66 69 6c 65 73 29  the Olson files)
8660: 0a 23 0a 23 20 50 61 72 61 6d 65 74 65 72 73 3a  .#.# Parameters:
8670: 0a 23 09 6f 75 74 44 69 72 20 2d 20 4e 61 6d 65  .#.outDir - Name
8680: 20 6f 66 20 74 68 65 20 64 69 72 65 63 74 6f 72   of the director
8690: 79 20 77 68 65 72 65 20 74 68 65 20 6f 75 74 70  y where the outp
86a0: 75 74 20 66 69 6c 65 73 20 67 6f 2e 0a 23 0a 23  ut files go..#.#
86b0: 20 52 65 73 75 6c 74 73 3a 0a 23 09 4e 6f 6e 65   Results:.#.None
86c0: 2e 0a 23 0a 23 20 53 69 64 65 20 65 66 66 65 63  ..#.# Side effec
86d0: 74 73 3a 0a 23 09 43 72 65 61 74 65 73 20 61 20  ts:.#.Creates a 
86e0: 66 69 6c 65 20 66 6f 72 20 65 61 63 68 20 6c 69  file for each li
86f0: 6e 6b 2e 0a 0a 70 72 6f 63 20 77 72 69 74 65 4c  nk...proc writeL
8700: 69 6e 6b 73 20 7b 6f 75 74 44 69 72 7d 20 7b 0a  inks {outDir} {.
8710: 20 20 20 20 76 61 72 69 61 62 6c 65 20 6c 69 6e      variable lin
8720: 6b 73 0a 0a 20 20 20 20 23 20 57 61 6c 6b 20 74  ks..    # Walk t
8730: 68 65 20 6c 69 6e 6b 73 0a 0a 20 20 20 20 66 6f  he links..    fo
8740: 72 65 61 63 68 20 7a 6f 6e 65 4e 61 6d 65 20 5b  reach zoneName [
8750: 6c 73 6f 72 74 20 2d 64 69 63 74 69 6f 6e 61 72  lsort -dictionar
8760: 79 20 5b 61 72 72 61 79 20 6e 61 6d 65 73 20 6c  y [array names l
8770: 69 6e 6b 73 5d 5d 20 7b 0a 09 70 75 74 73 20 22  inks]] {..puts "
8780: 63 72 65 61 74 69 6e 67 20 6c 69 6e 6b 3a 20 24  creating link: $
8790: 7a 6f 6e 65 4e 61 6d 65 22 0a 09 73 65 74 20 66  zoneName"..set f
87a0: 69 6c 65 4e 61 6d 65 20 5b 65 76 61 6c 20 5b 6c  ileName [eval [l
87b0: 69 73 74 20 66 69 6c 65 20 6a 6f 69 6e 20 24 6f  ist file join $o
87c0: 75 74 44 69 72 5d 20 5b 66 69 6c 65 20 73 70 6c  utDir] [file spl
87d0: 69 74 20 24 7a 6f 6e 65 4e 61 6d 65 5d 5d 0a 0a  it $zoneName]]..
87e0: 09 23 20 43 72 65 61 74 65 20 64 69 72 65 63 74  .# Create direct
87f0: 6f 72 69 65 73 20 61 73 20 6e 65 65 64 65 64 0a  ories as needed.
8800: 0a 09 73 65 74 20 64 69 72 4e 61 6d 65 20 5b 66  ..set dirName [f
8810: 69 6c 65 20 64 69 72 6e 61 6d 65 20 24 66 69 6c  ile dirname $fil
8820: 65 4e 61 6d 65 5d 0a 09 69 66 20 7b 21 5b 66 69  eName]..if {![fi
8830: 6c 65 20 65 78 69 73 74 73 20 24 64 69 72 4e 61  le exists $dirNa
8840: 6d 65 5d 7d 20 7b 0a 09 20 20 20 20 70 75 74 73  me]} {..    puts
8850: 20 22 63 72 65 61 74 69 6e 67 20 64 69 72 65 63   "creating direc
8860: 74 6f 72 79 3a 20 24 64 69 72 4e 61 6d 65 22 0a  tory: $dirName".
8870: 09 20 20 20 20 66 69 6c 65 20 6d 6b 64 69 72 20  .    file mkdir 
8880: 24 64 69 72 4e 61 6d 65 0a 09 7d 0a 0a 09 23 20  $dirName..}...# 
8890: 43 72 65 61 74 65 20 63 6f 64 65 20 66 6f 72 20  Create code for 
88a0: 74 68 65 20 73 79 6e 6f 6e 79 6d 0a 0a 09 73 65  the synonym...se
88b0: 74 20 6c 69 6e 6b 54 6f 20 24 6c 69 6e 6b 73 28  t linkTo $links(
88c0: 24 7a 6f 6e 65 4e 61 6d 65 29 0a 09 73 65 74 20  $zoneName)..set 
88d0: 73 6f 75 72 63 65 43 6d 64 20 22 5c 6e 20 20 20  sourceCmd "\n   
88e0: 20 5b 6c 69 73 74 20 4c 6f 61 64 54 69 6d 65 5a   [list LoadTimeZ
88f0: 6f 6e 65 46 69 6c 65 20 24 6c 69 6e 6b 54 6f 5d  oneFile $linkTo]
8900: 5c 6e 22 0a 09 73 65 74 20 69 66 43 6d 64 20 5b  \n"..set ifCmd [
8910: 6c 69 73 74 20 69 66 20 22 21 5c 5b 69 6e 66 6f  list if "!\[info
8920: 20 65 78 69 73 74 73 20 54 5a 44 61 74 61 28 24   exists TZData($
8930: 6c 69 6e 6b 54 6f 29 5c 5d 22 20 24 73 6f 75 72  linkTo)\]" $sour
8940: 63 65 43 6d 64 5d 0a 09 73 65 74 20 73 65 74 43  ceCmd]..set setC
8950: 6d 64 20 22 73 65 74 20 54 5a 44 61 74 61 28 3a  md "set TZData(:
8960: 24 7a 6f 6e 65 4e 61 6d 65 29 20 5c 24 54 5a 44  $zoneName) \$TZD
8970: 61 74 61 28 3a 24 6c 69 6e 6b 54 6f 29 22 0a 0a  ata(:$linkTo)"..
8980: 09 23 20 57 72 69 74 65 20 74 68 65 20 66 69 6c  .# Write the fil
8990: 65 0a 0a 09 73 65 74 20 66 20 5b 6f 70 65 6e 20  e...set f [open 
89a0: 24 66 69 6c 65 4e 61 6d 65 20 77 5d 0a 09 66 63  $fileName w]..fc
89b0: 6f 6e 66 69 67 75 72 65 20 24 66 20 2d 74 72 61  onfigure $f -tra
89c0: 6e 73 6c 61 74 69 6f 6e 20 6c 66 20 2d 65 6e 63  nslation lf -enc
89d0: 6f 64 69 6e 67 20 75 74 66 2d 38 0a 09 70 75 74  oding utf-8..put
89e0: 73 20 24 66 20 22 5c 23 20 63 72 65 61 74 65 64  s $f "\# created
89f0: 20 62 79 20 24 3a 3a 61 72 67 76 30 20 2d 20 64   by $::argv0 - d
8a00: 6f 20 6e 6f 74 20 65 64 69 74 22 0a 09 70 75 74  o not edit"..put
8a10: 73 20 24 66 20 24 69 66 43 6d 64 0a 09 70 75 74  s $f $ifCmd..put
8a20: 73 20 24 66 20 24 73 65 74 43 6d 64 0a 09 63 6c  s $f $setCmd..cl
8a30: 6f 73 65 20 24 66 0a 20 20 20 20 7d 0a 0a 20 20  ose $f.    }..  
8a40: 20 20 72 65 74 75 72 6e 0a 7d 0a 0a 23 2d 2d 2d    return.}..#---
8a50: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
8a60: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
8a70: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
8a80: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
8a90: 2d 2d 2d 0a 23 0a 23 20 4d 41 49 4e 20 50 52 4f  ---.#.# MAIN PRO
8aa0: 47 52 41 4d 0a 23 0a 23 2d 2d 2d 2d 2d 2d 2d 2d  GRAM.#.#--------
8ab0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
8ac0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
8ad0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
8ae0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 0a  --------------..
8af0: 70 75 74 73 20 22 43 6f 6d 70 69 6c 69 6e 67 20  puts "Compiling 
8b00: 74 69 6d 65 20 7a 6f 6e 65 73 20 2d 2d 20 5b 63  time zones -- [c
8b10: 6c 6f 63 6b 20 66 6f 72 6d 61 74 20 5b 63 6c 6f  lock format [clo
8b20: 63 6b 20 73 65 63 6f 6e 64 73 5d 20 5c 0a 09 20  ck seconds] \.. 
8b30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8b40: 20 20 20 20 20 20 20 20 20 20 2d 66 6f 72 6d 61            -forma
8b50: 74 20 7b 25 78 20 25 58 7d 20 2d 6c 6f 63 61 6c  t {%x %X} -local
8b60: 65 20 73 79 73 74 65 6d 5d 22 0a 0a 23 20 44 65  e system]"..# De
8b70: 74 65 72 6d 69 6e 65 20 64 69 72 65 63 74 6f 72  termine director
8b80: 69 65 73 0a 0a 6c 61 73 73 69 67 6e 20 24 61 72  ies..lassign $ar
8b90: 67 76 20 69 6e 44 69 72 20 6f 75 74 44 69 72 0a  gv inDir outDir.
8ba0: 0a 70 75 74 73 20 22 4f 6c 73 6f 6e 20 66 69 6c  .puts "Olson fil
8bb0: 65 73 20 69 6e 20 24 69 6e 44 69 72 22 0a 70 75  es in $inDir".pu
8bc0: 74 73 20 22 54 63 6c 20 66 69 6c 65 73 20 74 6f  ts "Tcl files to
8bd0: 20 62 65 20 70 6c 61 63 65 64 20 69 6e 20 24 6f   be placed in $o
8be0: 75 74 44 69 72 22 0a 0a 23 20 49 6e 69 74 69 61  utDir"..# Initia
8bf0: 6c 69 7a 65 20 63 6f 75 6e 74 20 6f 66 20 65 72  lize count of er
8c00: 72 6f 72 73 0a 0a 73 65 74 20 65 72 72 6f 72 43  rors..set errorC
8c10: 6f 75 6e 74 20 30 0a 0a 23 20 50 61 72 73 65 20  ount 0..# Parse 
8c20: 74 68 65 20 4f 6c 73 6f 6e 20 66 69 6c 65 73 0a  the Olson files.
8c30: 0a 6c 6f 61 64 46 69 6c 65 73 20 24 69 6e 44 69  .loadFiles $inDi
8c40: 72 0a 69 66 20 7b 24 65 72 72 6f 72 43 6f 75 6e  r.if {$errorCoun
8c50: 74 20 3e 20 30 7d 20 7b 0a 20 20 20 20 65 78 69  t > 0} {.    exi
8c60: 74 20 31 0a 7d 0a 0a 23 20 43 68 65 63 6b 20 74  t 1.}..# Check t
8c70: 68 61 74 20 61 6c 6c 20 72 69 6c 65 73 20 61 70  hat all riles ap
8c80: 70 65 61 72 69 6e 67 20 69 6e 20 5a 6f 6e 65 20  pearing in Zone 
8c90: 61 6e 64 20 4c 69 6e 6b 20 6c 69 6e 65 73 20 61  and Link lines a
8ca0: 63 74 75 61 6c 6c 79 20 65 78 69 73 74 0a 0a 63  ctually exist..c
8cb0: 68 65 63 6b 46 6f 72 77 61 72 64 52 75 6c 65 52  heckForwardRuleR
8cc0: 65 66 73 0a 69 66 20 7b 24 65 72 72 6f 72 43 6f  efs.if {$errorCo
8cd0: 75 6e 74 20 3e 20 30 7d 20 7b 0a 20 20 20 20 65  unt > 0} {.    e
8ce0: 78 69 74 20 31 0a 7d 0a 0a 23 20 57 72 69 74 65  xit 1.}..# Write
8cf0: 20 74 68 65 20 74 69 6d 65 20 7a 6f 6e 65 20 69   the time zone i
8d00: 6e 66 6f 72 6d 61 74 69 6f 6e 20 66 69 6c 65 73  nformation files
8d10: 0a 0a 77 72 69 74 65 5a 6f 6e 65 73 20 24 6f 75  ..writeZones $ou
8d20: 74 44 69 72 0a 77 72 69 74 65 4c 69 6e 6b 73 20  tDir.writeLinks 
8d30: 24 6f 75 74 44 69 72 0a 69 66 20 7b 24 65 72 72  $outDir.if {$err
8d40: 6f 72 43 6f 75 6e 74 20 3e 20 30 7d 20 7b 0a 20  orCount > 0} {. 
8d50: 20 20 20 65 78 69 74 20 31 0a 7d 0a 0a 23 20 41     exit 1.}..# A
8d60: 6c 6c 20 64 6f 6e 65 21 0a 0a 65 78 69 74 0a     ll done!..exit.