Calculate Eastern and other Holidays

A posting from Coen in the NF Integration forum (subject Active X) brought me to the idea to post this routine for calculating Holidays. Now you will say, “what’s the problem? Christmas is always December 25th”. Right! But what about days like Eastern (and depending holidays) which depend on the moon-phase? Right, it is possible to calculate moon phases in Navision. Quite compliated but nevertheless possible as I’m going to proove here. First note: If you are Swiss, German or Austrian, don’t use the routines posted here as plain text. You might instead download the zipped object in the German forum which calculates all holidays for the German speaking countries. Second and last note: The procedure EasterSunday is only valid to the year 8000. —


Procedure EasterSunday(CalendarYear : Integer) : Date;
Begin
  JH := CalendarYear DIV 100;
  J := CalendarYear MOD 100;  
  a := CalendarYear MOD 19;
  b := CalendarYear MOD 4;
  c := CalendarYear MOD 7;
  P := (15 + JH - JH DIV 3 - JH DIV 4) MOD 30;
  Q := (JH - JH DIV 4 + 4) MOD 7;
  d := (19 * a + P) MOD 30;
  e := (2 * b + 4 * c + 6 * d + Q) MOD 7;
  IF (d = 29) AND (e = 6) THEN
    k := 50     { Exception 1: --> 19th April }
  ELSE
    IF (d = 28) AND (e = 6) AND (a > 10) THEN
      k := 49   { Exception 2: --> 18th April }
    ELSE
      k := 22 + d + e;
  IF k <= 31 THEN
    exit(DMY2DATE (k,3,100*JH+J))
  ELSE
    exit(DMY2DATE (k-31,4,100*JH+J));
End;

--- 
... or what about calculating mother-day, the second sunday in May 2001? 
--> GetFactor(2,7,5,2001) ; speak: (second, sunday, may, 2001)

Procedure GetFactor(Which : Integer; DayOfWeek : Integer; Month : Integer; Year : Integer);
Begin
// Which --> 0 = Last, 1 = first day .... , 2 = second DayOfWeek in month
// DayOfWeek --> 1 = monday, 7 = sunday

locDate := DMY2DATE(1,Month ,Year );
locW := DATE2DWY (locDate,1);
IF (locW = 0) THEN
  locW := 7;
IF (Which = 0) THEN BEGIN
  locDate := CALCDATE(STRSUBSTNO('+%1D',35+DayOfWeek -locW));
  IF DATE2DMY(locDate,2) = Month THEN
    Which := 5
  ELSE
    Which := 4
END;
IF (locW <= DayOfWeek ) THEN
  Which := Which - 1;
EXIT (CALCDATE (STRSUBSTNO('+%1D',7*Which +DayOfWeek -locW),DMY2DATE(1,Month ,Year )));

— Hope you enjoy it! Marcus Fabian m.fabian@thenet.ch

This one is really great. I like it. Best regards, Erik P. Ernst, webmaster Navision Online User Group

I took some time to translate the original holiday calculating routines (basically a table and a form) into english. At least I translated the variables, functions and comments (as best as one can expect that to be done after midnight with a beer in the belly ) The holiday names are still in German language and you will find lots of holidays which you don’t know (I dont know most of them either). However I find it easier for you to delete unneeded holidays rather than making new entries. First you will have to translate the holidays to your language. I recommend to start form 50001 first, do an INIT to have all holidays calculated. That might help you to find out what to translate. I mean, you might not understand the German word “Weihnachten” but as this falls to December 25th, you might easily find out that it means “Christmas”. Second you will have to delete all the unimportant holidays including national holiday of Switzerland, Austria, Germany if you don’t need them. Third you will have to add your own national holidays. However, you will find that this is very easy to accomplish. To add e.g. the 14th of July, simply add the statement AddHoliday (DMY2DATE(14,7,CalendarYear),‘French national holiday’,TRUE); in the InitHolidays function which is part of Table 50000 The TRUE as last parameter states that this holiday is important (at least: pour les français). I guess you won’t have problems to figure out. The heart of the routines are the calculation of Eastern as well as some date-calculations which help you to find out e.g.: “the 3rd Wednesday in May” or “the first sunday after october 31st” etc. Even if you don’t need this holiday table, you might still want to use the date-calc routines included. If you take the time to adapt the InitHoliday function to the requirements of your nation/religion, please be so kind to post your results back to the forum. There’s no need that 20 Americans all do the same changes. One last personal request. I consider these routines as shareware. Which means you might freely use, change and sell them as you wish, providing you grant me the following wish: 1. Buy a postcard of your hometown. 2. On the postcard write down the name and address of your favourite restaurant and include what you would recommend to eat/drink there. 3. Send the postcard to me: Marcus Fabian, Holzgasse 29, 3322 Schoenbuehl, Switzerland Enjoy! download holidays NF 2.60 Marcus Fabian m.fabian@thenet.ch