TITLE:Tracking Calendar Holidays
ISSUE:Multi-value Solutions Mar '98
AUTHOR:Nathan Rector
COMPANY:Natec Systems
EMAIL:nater@northcoast.com
HTTP:www.northcoast.com/~nater/
Keeping track of holidays is often over looked in many date-related programs. I've seen a few payroll programs that didn't know if the day the user input was a holiday or a regular day. Also I've seen several programs in the rental industry that didn't know if a day was a holiday or not, or didn't allow a MIS person change or add holidays to track.
The programs that do keep track of holidays often only track the key holidays like Christmas and Thanksgiving. Unfortunately, in some industries, it is also important to keep track of other holidays like Columbus Day and Memorial Day.
Another weakness I've seen in holiday programs is when the business opens or closes on that day. For example, Christmas Eve is just as important to people as Christmas, but many company close at noon rather than their normal time. Or a business may stay open until 12 am on Valentine’s Day for those people who forgot to get things.
The following Holiday program (Figure 2) allows you to specify all these things and use it in almost any applications from automatically paying for holidays in payroll to just displaying a special day on someone's appointment calendar.
To use this program a Holiday record needs to be created. (See Figure 1 for an example.) This can be done using the EDIT Holdiay.supt holiday command. The record should be structured as follows:
002 Month of holiday
003 Day of holiday
004 Holiday Name
005 Special program to create the holiday
006 Type of holiday 0- closed, nonpaid, 1- closed, paid, 2- Not closed
007 Close time
The program allows you to pass a date range which it checks against all the holidays. If there is a holiday in the date range, then it returns the list of holidays in the date range with the actual day of the holiday, the type of holiday, and the closing time for the holiday.
Since the program can be told to return only a specific type of holiday it can be used in many different programs. By setting ACTION to '1' the program returns only paid closed holidays. By setting ACTION to '2' the program returns all closed holidays regardless if the holiday is paid or not. Leaving the ACTION null returns all the holidays for the date range.
This powerful program is very handy for appointment calendars, payroll programs, dispatcher control, and rental reserve and pricing programs. In addition, I’ve enclosed the programs that calculated the date of Easter, Thanksgiving, and Labor Day. If you have other holidays that don’t always fall on the same date, similiar programs can be created.
This program is very powerful and very handy. I've found a user for it in appointment calendars, payroll programs, dispatcher control, and rental reserve and pricing programs.
:list holiday.supt "holiday" (i
Month Day Desc................ Program............. Type Close.....
1 1 New Years 1
Easter EASTER 1
7 4 Independence Day 1
Thanksgiving THANKSGIVING 1
12 25 X-Mas 1
Labor day LABOR.DAY1 0
2 14 Valentine's Day 2
10 31 Halloween 2
12 31 New Year's Eve 2 12:00PM
12 24 X-Mas Eve 2 12:00PM
holiday1
001 SUBROUTINE HOLIDAY1(ACTION,BEG.DATE,END.DATE,HOLIDAY.DATE,NONE1,NONE2,NONE3,NONE4,NONE5,REDO)
002 EQUATE AM TO CHAR(254), VM TO CHAR(253), SVM TO CHAR(252)
003 EQUATE BELL TO CHAR(7)
004 *
005 *
006 *CREATED BY NATHAN RECTOR, 02/12/96
007 *
008 *USED IN OTHER PROGRAMS
009 *
010 *
011 * D O C U M E N T A T I O N
012 *
013 * This program is used to see if there is a holiday in the date range
014 *
015 * ACTION = 1 - returns only paid holidays
016 * 2 - returns only holidays we are closed on
017 *
018 * HOLIDAY.DATE<1,n> = is the dates of all the holidays that fall
019 * within the date range
020 * <2,n> = the description of the holiday
021 * <3,n> = the type of holiday. 0- closed,nonpaid, 1- closed,paid, 2- not closed
022 * <4,n> = Time close
023 *
024 * REDO = 1 - no holiday's match for this time
025 * 2 - holiday's
026 *
027 * INPUT 'Y' to continue OR 'N' to return to Menu.
028 *
029 *********************************************************************
030 *OPEN FILES
031 *********************************************************************
032 OPEN "HOLIDAY.SUPT" TO HOLIDAY.SUPT.FILE ELSE STOP 201, "HOLIDAY"
033 *********************************************************************
034 *PROGRAMMING LOGIC
035 *********************************************************************
036 REDO = 1 ; HOLIDAY.DATE = ""
037 READ HOLIDAY.ITEM FROM HOLIDAY.SUPT.FILE, "HOLIDAY" ELSE HOLIDAY.ITEM = ""
038 *
039 YEAR.ST = OCONV(BEG.DATE,"DY")
040 YEAR.FN = OCONV(END.DATE,"DY")
041 *
042 FOR YEAR = YEAR.ST TO YEAR.FN
043 FOR I = 1 TO I + 1 UNTIL HOLIDAY.ITEM<4,I> = ""
044 BEGIN CASE
045 CASE NOT(HOLIDAY.ITEM<5,I> = "")
046 PROG = HOLIDAY.ITEM<5,I>
047 CALL @PROG(YEAR,DATE,"","","","")
048 CASE 1
049 DATE = ICONV(HOLIDAY.ITEM<2,I> :"/": HOLIDAY.ITEM<3,I> :"/": YEAR,"D")
050 END CASE
051 *
052 BEGIN CASE
053 CASE ACTION = 1 AND NOT(HOLIDAY.ITEM<6,I> = 1)
054 * not a paid holiday
055 CASE ACTION = 2 AND HOLIDAY.ITEM<6,I> = 2
056 * not closed on this holiday
057 CASE DATE >= BEG.DATE AND DATE <= END.DATE
058 REDO = 2
059 HOLIDAY.DATE<1,-1> = DATE
060 HOLIDAY.DATE<2,-1> = HOLIDAY.ITEM<4,I>
061 HOLIDAY.DATE<3,-1> = HOLIDAY.ITEM<6,I> ;* type of holiday
062 HOLIDAY.DATE<4,-1> = ICONV(HOLIDAY.ITEM<7,I>,"MT")
063 END CASE
064 NEXT I
065 NEXT YEAR
066 900*
067 RETURN
068 END
easter
001 SUBROUTINE EASTER(YEAR,EASTER,NONE,NONE2,NONE3,NONE4)
002 EQUATE AM TO CHAR(254), VM TO CHAR(253), SVM TO CHAR(252)
003 EQUATE BELL TO CHAR(7)
004 *
005 *CREATED BY NATHAN RECTOR, 01/06/93
006 *
007 *USED IN OTHER PROGRAMS
008 *
009 *
010 * D O C U M E N T A T I O N
011 *
012 * This program will calc the date of easter.
013 *
014 * INPUT 'Y' to continue OR 'N' to return to Menu.
015 *
016 *********************************************************************
017 *PROGRAMMING LOGIC
018 *********************************************************************
019 *
020 VAR1 = YEAR - INT(YEAR / 19) * 19
021 VAR2 = YEAR - INT(YEAR / 4) * 4
022 VAR3 = YEAR - INT(YEAR / 7) * 7
023 VAR4 = (19 * VAR1) + 24
024 VAR5 = VAR4 - INT(VAR4 / 30) * 30
025 VAR6 = 2 * VAR2 + 4 * VAR3 + 6 * VAR5 + 5
026 VAR7 = VAR6 - INT(VAR6 / 7) * 7
027 VAR8 = VAR5 + VAR7 - 9
028 *
029 BEGIN CASE
030 CASE VAR8 > 0
031 BEGIN CASE
032 CASE VAR8 = 26
033 EASTER = ICONV("4/19/":YEAR,"D2/")
034 CASE VAR8 # 25
035 EASTER = ICONV("4/":VAR8:"/":YEAR,"D2/")
036 CASE VAR8 = 28
037 EASTER = ICONV("4/18/":YEAR,"D2/")
038 CASE 1
039 EASTER = ICONV("3/":VAR8:"/":YEAR,"D2/")
040 END CASE
041 CASE 1
042 DAY = VAR8 + 31
043 EASTER = ICONV("3/":DAY:"/":YEAR,"D2/")
044 END CASE
045 *
046 RETURN
047 END
labor.day1
001 SUBROUTINE LABOR.DAY1(YEAR,LABOR.DAY,NONE,NONE2,NONE3,NONE4)
002 EQUATE AM TO CHAR(254), VM TO CHAR(253), SVM TO CHAR(252)
003 EQUATE BELL TO CHAR(7)
004 *
005 *CREATED BY NATHAN RECTOR, 01/06/93
006 *
007 *USED IN OTHER PROGRAMS
008 *
009 *
010 * D O C U M E N T A T I O N
011 *
012 * This program will calc the date of LABOR.DAY1.
013 *
014 * INPUT 'Y' to continue OR 'N' to return to Menu.
015 *
016 *********************************************************************
017 *PROGRAMMING LOGIC
018 *********************************************************************
019 *
020 LABOR.DAY = ICONV("09/01/":YEAR,"D")
021 *
022 FOR LABOR.DAY = LABOR.DAY TO LABOR.DAY + 1 UNTIL (LABOR.DAY 'DW' = 1) ; NEXT LABOR.DAY
023 900*
024 RETURN
025 END
thanksgiving
001 SUBROUTINE THANKSGIVING(YEAR,DATE,NONE,NONE2,NONE3,NONE4)
002 EQUATE AM TO CHAR(254), VM TO CHAR(253), SVM TO CHAR(252)
003 EQUATE BELL TO CHAR(7)
004 *
005 *CREATED BY NATHAN RECTOR, 01/06/93
006 *
007 *USED IN OTHER PROGRAMS
008 *
009 *
010 * D O C U M E N T A T I O N
011 *
012 * This program will calc the date of Thanksgiving.
013 *
014 * INPUT 'Y' to continue OR 'N' to return to Menu.
015 *
016 *********************************************************************
017 *PROGRAMMING LOGIC
018 *********************************************************************
019 *
020 DATE = ICONV("11/30/":YEAR,"D") ; DAY = 1
021 *
022 *** checks for the last thursday of the month
023 *
024 LOOP
025 UNTIL OCONV(DATE,"DW") = 4 DO
026 DATE = DATE - 1
027 REPEAT
028 *
029 RETURN
030 END