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.