# compute holidays

Feb 27th, 2020
1,817
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. proc vmc_holidays { year } {
2.     set res {}
3.
4.     # Memorial day, labor day, Thanksgiving
5.     foreach { month dow lim ind } {
6.         05 1 31 end
7.         09 1 30 0
8.         11 4 30 3
9.     } {
10.         set s2 {}
11.         # get the numeric day of the week for the first of the month
12.         set s [clock format [clock scan [format "%s%s01" \$year \$month]] -format %w]
13.         # find the day of month of the first monday or thurs
14.         set day [expr (7+\$dow-\$s)%7+1]
15.         while { \$day <= \$lim } {
16.             # add the date of each matching day of the week in the month to a list
17.             lappend s2 [format "%s%s%02d" \$year \$month \$day]
18.             incr day 7
19.         }
20.         # pick out just date specified by "ind" above
21.         lappend res [lindex \$s2 \$ind]
22.     }
23.
24.     # new years, independence, christmas & eve, new years observed
25.     foreach x { 0101 0704 1225 1231 } {
26.         set d "\$year\$x"
27.         set s [clock scan \$d]
28.         set dow [clock format \$s -format %a]
29.
30.         if { \$x eq "1231" && \$dow ne "Fri" } {
31.             # new years day observed on Fri, 12/31
32.             continue
33.         }
34.
35.         if { \$x eq "1225" } {
36.             # compute where christmas and christmas eve fall
37.             if { \$dow eq "Sat" } {
38.                 lappend res [clock format [clock add \$s -2 days] -format %Y%m%d]
39.                 set s [clock add \$s -1 day]
40.             } elseif { \$dow eq "Sun" } {
41.                 lappend res [clock format [clock add \$s -2 days] -format %Y%m%d]
42.                 set s [clock add \$s 1 day]
43.             } elseif { \$dow eq "Mon" } {
44.                 lappend res [clock format [clock add \$s 1 days] -format %Y%m%d]
45.             } else {
46.                 lappend res [clock format [clock add \$s -1 days] -format %Y%m%d]
47.             }
48.         } elseif { \$dow eq "Sat" } {
49.             if { \$x eq "0101" } {
50.                 # this was observed last year
51.                 continue
52.             }
53.             set s [clock add \$s -1 day]
54.         } elseif { \$dow eq "Sun" } {
55.             set s [clock add \$s 1 day]
56.         }
57.         lappend res [clock format \$s -format %Y%m%d]
58.     }
59.     return [lsort \$res]
60. }