Command file tests 3000s for holidays
October 26, 2018
Holiday season is coming up. It's already upon us all at the grocery stores, where merchandising managers have cartons of Thanksgiving decorations waiting their turn. The Halloween stuff has to clear away first.
Community contributor Dave Powell has improved upon a command file created by Tracy Pierce to deliver a streamlined way to tell an HP 3000 about upcoming holidays. Datetest tells whether a day is a holiday. "I finally needed something like that," Powell says, "but I wanted the following main changes:
1: Boolean function syntax, so I could say :if holiday() then instead of
:xeq datetest
:if WhichVariableName = DontRememberWhatValue thenand also because I just think user-functions are cool.
2. Much easier to add or disable specific holidays according to site-specific policies or even other countries’ rules. (Then disable Veterans Day, Presidents Day and MLK Day, because my company doesn’t take them.)
3. Make it easy to add special one-off holidays like the day before/after Christmas at the last minute when the company announces them.
Along the way, I also added midnight-protection and partial input date-checking, and made it more readable, at least to me.
Powell, who's contributed plenty of command files to the community through the HP 3000 newsgroup, says that most of the fun came in the day-of-week calculation.
I didn’t understand that part of Tracy’s script, or trust myself to adapt it without messing up, so I found a second method and used both, with a warning if the results didn’t agree. Surprise, surprise, they disagree about 12/25/2100, although they agree on dates I tested within the expected lifespan of MPE. So I shoveled in a third formula and found a day-of-week calculator spreadsheet, both of which agree with the second method. So anyone who uses Tracy’s original command file and plans to still run it in 2100 might need to make a change.
He offered what he called a preliminary version of the new datetest, which has been checked by Allegro's Steve Cooper
option nolist
parm CCYYMMDD = ""
if bound (HOL_ERRORS) or bound (HOL_DAY)
deletevar HOL_@
endif
setvar HOL_ERRORS 0
if "!CCYYMMDD" = ""
setvar HOL_CYMD HPYYYYMMDD
setvar HOL_DAY !HPDAY
if HOL_CYMD <> HPYYYYMMDD
# if the date has changed, we just hit midnite and the
# day-of-week we just set might be the new day; in this
# case set the date & day-of-week again, and we should
# be ok (unless the following 2 commands take 24 hours :)
setvar HOL_CYMD HPYYYYMMDD
setvar HOL_DAY !HPDAY
endif
else
setvar HOL_CYMD "!CCYYMMDD"
if not numeric (HOL_CYMD)
echo **date parm, if entered, must be numeric**
setvar HOL_ERRORS HOL_ERRORS + 1
endif
if len (HOL_CYMD) <> 8
echo **date parm must be exactly 8 digits, unless omitted**
setvar HOL_ERRORS HOL_ERRORS + 1
elseif numeric (HOL_CYMD)
if rht (HOL_CYMD, 2) > "31"
echo **last 2 digits of date parm can't be more than 31**
setvar HOL_ERRORS HOL_ERRORS + 1
elseif rht (HOL_CYMD, 2) = "00"
echo **last 2 digits of date parm can't be "00"**
setvar HOL_ERRORS HOL_ERRORS + 1
endif
if str (HOL_CYMD, 5, 2) > "12"
echo **bytes 5 & 6 of date parm can't be more than 12**
setvar HOL_ERRORS HOL_ERRORS + 1
elseif str (HOL_CYMD, 5, 2) = "00"
echo **characters 5 & 6 of date parm can't be "00"**
setvar HOL_ERRORS HOL_ERRORS + 1
endif
endif
if HOL_ERRORS > 0
echo **exiting because the date-parm was not a valid**
echo **8-digit date in yyyymmdd format **
return FALSE
endif
endif
# -------------------------------------------------------
# do not casually modify above here
#
# Take any special / unofficial holidays here
# OK to replace any dates that are past with the date of a
# holiday the company just announced (Jewish new year,
# days before / after Christmas & New Years, etc, etc)
if HOL_CYMD="20080929" or HOL_CYMD="20081008" &
or HOL_CYMD="20081226" or HOL_CYMD="20090102"
echo It's a special company holiday :)
return TRUE
endif
# do not casually modify below here
# -------------------------------------------------------
setvar HOL_YYYY str (HOL_CYMD, 1, 4)
setvar HOL_MM str (HOL_CYMD, 5, 2)
setvar HOL_DD str (HOL_CYMD, 7, 2)
#
# Set day of week, unless already set because processing "today"
#
if not bound (HOL_DAY)
# 1st, the method in the original "datetest" command file
setvar HOL_DAY str("000031059090120151181212243273304334", &
!HOL_MM * 3 - 2, 3)
setvar HOL_DAY !HOL_DAY + !HOL_DD
IF !HOL_MM > 2 and ( !HOL_YYYY / 4 * 4 = !HOL_YYYY )
setvar HOL_DAY HOL_DAY + 1
ENDIF
setvar HOL_YWK !HOL_YYYY - 1
setvar HOL_DAY !HOL_DAY + ( !HOL_YWK / 400 ) * 146097
setvar HOL_YWK !HOL_YWK mod 400
setvar HOL_DAY !HOL_DAY - ( !HOL_YWK / 100 ) * 36524
setvar HOL_YWK !HOL_YWK mod 100
setvar HOL_DAY !HOL_DAY + ( !HOL_YWK / 4 ) * 1461
setvar HOL_YWK !HOL_YWK mod 4
setvar HOL_DAY !HOL_DAY + ( !HOL_YWK * 365 )
setvar HOL_DAY ( HOL_DAY mod 7 ) + 1
deletevar HOL_YWK
# Next, the method posted to the 3000-l by Mike Hornsby 06/04/2004
# except, add 1 at the end because his was 0-6 and we need
# 1-7.
setvar HOL_XYR !HOL_YYYY-((12-!HOL_MM)/10)
setvar HOL_XMONTH !HOL_MM+(((12-!HOL_MM)/10)*12)
setvar HOL_XDAY !HOL_DD+(!HOL_XMONTH*2)+(((!HOL_XMONTH+1)*6)/10)
setvar HOL_XLEAP_YR (HOL_XYR/4) - (HOL_XYR/100) + (HOL_XYR/400)
setvar HOL_XDAY (HOL_XDAY+HOL_XYR+HOL_XLEAP_YR+1) mod 7 + 1
# Next, day-of-week with my adaption of a "Zeller" formula
# off the internet.
if HOL_MM < "03"
setvar HOL_ZMONTH !HOL_MM + 12
setvar HOL_ZYEAR !HOL_YYYY - 1
else
setvar HOL_ZMONTH !HOL_MM
setvar HOL_ZYEAR !HOL_YYYY
endif
setvar HOL_ZDAY ( &
((13 * HOL_ZMONTH + 3) / 5) + !HOL_DD + HOL_ZYEAR &
+ (HOL_ZYEAR/4) - (HOL_ZYEAR/100) + (HOL_ZYEAR/400) &
+ 1 ) mod 7 + 1
# Now, see if the day-of-week calcs agree
if HOL_DAY <> HOL_XDAY &
or HOL_DAY <> HOL_ZDAY &
or HOL_ZDAY <> HOL_XDAY
setvar HOL_ERRORS HOL_ERRORS + 1
echo **day-of-week error**
echo HOL_DAY = !HOL_DAY
echo HOL_XDAY = !HOL_XDAY
echo HOL_ZDAY = !HOL_ZDAY
endif
setvar HOL_DAY HOL_ZDAY
deletevar HOL_X@, HOL_Z@
ENDIF
#
# Now check for specific regular holidays, month-by-month.
if HOL_MM = "01"
if HOL_DD = "01"
echo It's New Years Day
return TRUE
endif
if ( !HOL_DAY=2 and !HOL_DD>=15 and !HOL_DD<=21 )
echo (It's Martin Luther King day - but do we get it?)
# return TRUE
endif
return FALSE
elseif HOL_MM = "02"
if (!HOL_DAY=2 and !HOL_DD>=15 and !HOL_DD<=21)
echo (It's President's Day - but do we get it?)
# return TRUE
endif
return FALSE
elseif HOL_MM = "05"
if (!HOL_DAY=2 and !HOL_DD>=25 and !HOL_DD<=31)
echo It's Memorial Day
return TRUE
endif
return FALSE
elseif HOL_MM = "07"
if HOL_DD = "04"
echo It's July 4th
return TRUE
endif
return FALSE
elseif HOL_MM = "09"
if ( !HOL_DAY=2 and !HOL_DD>=1 and !HOL_DD<=7 )
echo It's Labor Day
return TRUE
endif
return FALSE
elseif HOL_MM = "11"
if HOL_DD = "11"
echo (it's Veterans Day - but do we get it ?)
# return TRUE
endif
if ( !HOL_DAY=5 and !HOL_DD>=22 and !HOL_DD<=28 )
echo It's Thanksgiving
return TRUE
endif
if ( !HOL_DAY=6 and !HOL_DD>=23 and !HOL_DD<=29 )
echo It's the day after Thanksgiving
return TRUE
endif
return FALSE
elseif HOL_MM = "12"
if HOL_DD = "25"
echo It's Christmas
return TRUE
endif
return FALSE
endif