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