#ifdef never Kalender-Algorithmen und das Kirchenjahr

Kalender-Algorithmen
und das Kirchenjahr

Das unten wiedergegebene Programm calend.c berechnet zu einem Jahr die kirchlichen Feiertage (in Deutschland) sowie optional den Kirchenkalender mit allen Sonntagsnamen und den Altarsfarben.

Download: calend.zip, calend.c = index.html, calend.exe, makefile - 21 kB

Das Kirchenjahr richtet sich nach 3 Zeitpunkten im Jahr:

  1. Erster Advent - Beginn des Kirchenjahrs (der 4. Advent ist der Sonntag vor oder am 24.12.),
  2. Heilige Drei Könige = Epiphanias, 6. Januar
  3. Ostersonntag, dem 1. Sonntag nach dem ersten Vollmond, der nach dem Frühlingsanfang (21.3.) erscheint.
Je nach Lage des Ostersonntags und der Wochentage im Jahr Mit dem Programm lassen sich z.B. Fragen beantworten wie die in der folgenden EMail:
Wissen Sie, warum es so schwierig ist, einfach nur Termine des aktuellen Kirchenjahrs zu bekommen. Was ist zum Beispiel heute (04.02.01) für ein Kirchensonntag? Es ist nicht Septuagesimä, denn das wäre laut meiner Information der 9. Sonntag vor Ostern, es ist nicht der 4. Sonntag nach Epiphanias! Zum Hintergrund meiner Frage: Ich habe auf CD sämtliche Bach-Kantaten, die sich ja auf die jeweiligen Kirchensonntage beziehen, es gelingt mir aber nicht, eine verlässliche Auskunft darüber zu bekommen, welche Bach-Kantate zum Beispiel heute dran wäre.
Johann Sebastian Bach schrieb je eine Kantate für jeden Sonn- und Feiertag in 5 Jahreszklen. Von diesen ca. 300 Kantaten sind heute noch rund 200 bekannt.
Das Programm enthält eine Reihe von Kalender-Algorithmen in der Form von C-Funktionen: Die Algorithmen sind meistens angepasste Versionen von Programmen, die in der Literatur veröffentlicht wurden, insbesondere in den Communications of the ACM.

Die meisten Algorithmen sind Jahr-2000-fest, allerdings gibt der Autor hierfür keinerlei Garantie. Das Programm enthält auch Testtreiber, die die Ergebnisse der verschiedenen Algorithmen miteinander vergleichen.


#endif
/*  calend.c - Calendar Functions + Church Calendar
    Copyright (C) 1995 punctum-transfer Dr. Georg Fischer, D-79341 Kenzingen
    V2.6, 20-Dec-2000: ANSI Umlauts, less -k sundays
    V2.5, 16-Nov-1999: 4th Advent on 24-Dec also
    V2.4, 07-May-1999: HTMLized, parament colors in col. 2,
                       Johannis, Michaelis, delimited with "|"
    V2.3, 28-Jan-1998: catholic sunday/holy day names
    V2.2, 01-Dec-1996: full year output for church calendar
    V2.1, 24-Jul-1995: parameters of 'easter*' reversed, new 'week_in_year'
    V2.0, 20-Jul-1995: in C
    V1.0, 18-Feb-1973: in FORTRAN

    Activation:

    calend  1998     
    calend -h 1998   holy days only

    calend -c 1996   catholic church year with all sundays (German)
    calend -k 1996   catholic also, but less sunday names

    calend -e 1998   evangelic church year

*/
#include  
#include    /* strcpy */
#include     /* isdigit */
#include   /* exit */

#define PUBLIC  extern
  /* must be redefined empty if interface file is included in implem. file */
#define PRIVATE static
  /* the opposite of PUBLIC */

#define ord(character) (character)
#define chr(integer)   (integer & 0xff)

#define TRUE    1
#define FALSE   0
#define BOOL    int
#define BYTE    unsigned char
#define WORD    unsigned int

#define ANSI

/* prototype suppression if not ANSI */
#ifdef  ANSI
#define PRO0()                        (void)
#define PRO1(t1)                      (t1)
#define PRO2(t1, t2)                  (t1, t2)
#define PRO3(t1, t2, t3)              (t1, t2, t3)
#define PRO4(t1, t2, t3, t4)          (t1, t2, t3, t4)
#define PRO5(t1, t2, t3, t4, t5)      (t1, t2, t3, t4, t5)
#define PRO6(t1, t2, t3, t4, t5, t6)  (t1, t2, t3, t4, t5, t6)
#else
#define PRO0()                        ()
#define PRO1(t1)                      ()
#define PRO2(t1, t2)                  ()
#define PRO3(t1, t2, t3)              ()
#define PRO4(t1, t2, t3, t4)          ()
#define PRO5(t1, t2, t3, t4, t5)      ()
#define PRO6(t1, t2, t3, t4, t5, t6)  ()
#endif

/*--------------------------------------------------------*/
#define EVANGELIC  1
#define CATHOLIC   2
#define KATHOLISCH 3

PUBLIC  int  day_in_year    PRO3 (int  day,  int  month, int  year);
PUBLIC  void day_to_date    PRO4 (int  year, int  day_num,
                                  int  *day, int  *month);
PUBLIC  int  week_day       PRO3 (int  day,  int  month, int  year);
PUBLIC  long julian_date    PRO3 (int  day,  int  month, int  year);
PUBLIC  void gregorian_date PRO4 (long julian,
                                  int  *day, int  *month, int  *year);
PUBLIC  int  week_in_year   PRO3 (int  day,  int  month,  int  year);

PUBLIC  void easter1        PRO3 (int  eyear,   int  *emonth, int  *eday);
PUBLIC  void easter2        PRO3 (int  eyear,   int  *emonth, int  *eday);
PUBLIC  void easter3        PRO3 (int  eyear,   int  *emonth, int  *eday);
PUBLIC  void easter_test    PRO0 ();
PUBLIC  void calend_test    PRO0 ();

PUBLIC  void holy_days      PRO1 (int  year);
PUBLIC  void church_year    PRO2 (int  year, int church);

PRIVATE char wd_name[7][3] = {"Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"};

/*--------------------------------------------------------

*/

PUBLIC  int  day_in_year (day, month, year)
  /* compute the sequential number of a day in the year
     (1-Jan = 1, 31-Dec = 365/366)
     J.D. Robertson: Remark on Algorithm 398,
     Comm. ACM 13, 10 (Oct. 1972), p. 918
  */
  int  day, month, year;
  { /* day_in_year */
    int  lmon; /* derived from month */

    lmon = (month + 10) / 13;
    return (((long) 3055 * (long) (month + 2)) / 100 - 2 * lmon - 91
            + (1
            - (year - (year /   4) *   4 +   3) /   4
            + (year - (year / 100) * 100 +  99) / 100
            - (year - (year / 400) * 400 + 399) / 400
            ) * lmon + day);
  } /* day_in_year */

/*--------------------------------------------------------

*/
PUBLIC  void day_to_date (year, day_num,   day, month)
  /* compute the date from the sequential number of a day in the year
     (1-Jan = 1, 31-Dec = 365/366)
     inverse to 'day_in_year'
     valid only for 1900 < year < 2100
  */
  int  year, day_num;
  int  *day;
  int  *month;
  { /* day_to_date */
    int  leap; /* = 1 (0) if (no) leap year */
    int  cfeb; /* correction for February */
    int  tday; /* temporary day number */

    if (year % 4 == 0)
      leap = 1;
    else
      leap = 0;
    if (day_num > 59 + leap)
      cfeb = 2 - leap;
    else
      cfeb = 0;
    tday = day_num  + cfeb + 91;
    *month = (long) ((long) tday * 100l) / 3055;
    *day   = tday - (long) ((long) *month * 3055l) / 100;
    *month -= 2;
  } /* day_to_date */

/*--------------------------------------------------------

*/
PUBLIC  int  week_day (day, month, year)
  /* compute the day in the week,
     1 = Monday, 7 = Sunday
     J.D. Robertson: Remark on Algorithm 398,
     Comm. ACM 13, 10 (Oct. 1972), p. 918
     "Zeller's congruence"
  */
  int  day, month, year;
  { /* week_day */
    int  lmon; /* derived from month */
    int  mmon; /* derived from month */

    lmon = month + 10;
    mmon = (month - 14) / 12 + year;
    return ((((13 * (lmon - (lmon /  13) *  12) - 1) / 5 + day + 77
              + 5 * (mmon - (mmon / 100) * 100) / 4
             + mmon / 400 - (mmon / 100) *   2)
             - 1) % 7 + 1
           );
  } /* week_day */

/*--------------------------------------------------------

*/
PUBLIC  int  week_in_year (day, month, year)
  /* Compute the week number (0..52) for a given date.
     The weeks start at monday, and some days at the beginning
     of January may be in week "0"
     which means week 52 of the previous year.
  */
  int  day, month, year;
  { /* week_in_year */
    int  wjan1; /* week day of January 1st */
    int  day_num; /* number of day in year */

    wjan1 = week_day (1, 1, year);
    day_num = day_in_year (day, month, year);
    if (wjan1 > 1)
      day_num -= (8 - wjan1);
    if (day_num <= 0)
      return 0; /* before 1st Monday in January */
    else
      return (day_num - 1) / 7 + 1;
  } /* week_in_year */

/*--------------------------------------------------------

*/
PUBLIC  long julian_date (pday, pmonth, pyear)
  /*  Compute the Julian date (number) from a Gregorian calendar date.
      The result is a count of days starting at "the creation of the world"
      in 4713 B.C.

      Both days start at 0 h Universal Time,
      while in astronomy the Julian day usually starts at 12 h UT.

      Fliegel, H.F., Van Flandern, T.C.:
      A Machine Algorithm for Processing Calendar Dates.
      Comm. ACM 11, 10 (Oct. 1968), p. 657

      restriction: 'pyear > 1600' (Gregorian calendar)
      test values:
        01-Jan-1979 -> 2443875
        01-Jan-1900 -> 2415021
        01-Jan-1970 -> 2440588
        28-Aug-1940 -> 2429870 (Robert B. Wooster)
  */
  int  pday, pmonth, pyear;
  { /* julian_date */
    long day, month, year; /* copies of the parameters */
    long mmon; /* derived from month */

    day   = pday;
    month = pmonth;
    year  = pyear;
    mmon  = (month - 14) / 12;
    return day - 32075L + 1461L * (year + 4800L + mmon) / 4L
           + 367L * (month - 2L - mmon * 12L) / 12L - 3L
           * ((year + 4900L + mmon) / 100L) / 4L;
  } /* julian_date */

/*--------------------------------------------------------

*/
PUBLIC  void gregorian_date (julian,   day, month, year)
  /*  Compute the Gregorian calendar date from a Julian date (number)
      (inverse of 'julian_date').

      Fliegel, H.F., Van Flandern, T.C.:
      A Machine Algorithm for Processing Calendar Dates.
      Comm. ACM 11, 10 (Oct. 1968), p. 657

      for example, 'julian_date (1, 1, 1970) == 2440588'
      restriction: 'year > 1600' (Gregorian calendar)
  */
  long julian;
  int  *day, *month, *year;
  { /* gregorian_date */
    long ljul; /* derived from 'julian' */
    long njul; /* derived from 'julian' */
    long lmon; /* yields '*month' */
    long lyea; /* yields '*year' */

    ljul   = julian + 68569L;
    njul   = 4L * ljul / 146097L;
    ljul   = ljul - (146097L * njul + 3L) / 4L;

    lyea   = (int) (4000L * (ljul + 1L) / 1461001L);
    ljul   = ljul - 1461L * lyea / 4L + 31L;
    lmon   = 80L * ljul / 2447L;
    *day   = (int) (ljul - 2447L * lmon / 80L);
    ljul   = lmon / 11L;
    *month = (int) (lmon + 2L - 12L * ljul);
    *year  = (int) (100L * (njul - 49L) + lyea + ljul);
  } /* gregorian_date */

/*--------------------------------------------------------

*/
PUBLIC  void easter1 (eyear,   eday, emonth)
  /* Donald E. Knuth, Comm. ACM 5, April 1962, pp. 206 - 210

     This procedure calculates the day and month of easter given
     the year. It gives the actual date of WESTERN easter (not the
     EASTERN easter of the eastern orthodox churches) after A.D. 463.

     'epact' specifies when full moon occurs.

     Easter is the first sunday following the first full moon which
     occurs on or after March 21 (= equinox, start of spring).

     Reference: A. de Morgan, A Budget of Paradoxes.
  */
  int  eyear; /* calculate Easter for this year */
  int  *eday; /* day of Easter */
  int  *emonth; /* month of Easter */
  { /* easter1 */
    int  golden_number;
      /* number of the year in the metonic cycle,
         used to determine the position of the calendar moon */
    int  century;
    int  gregorian_correction;
      /* number of preceeding years like 1700, 1800, 1900
         when leap year was not held */
    int  clavian_correction;
      /* correction for the metonic cycle of about 8 days every 2500 years */
    int  extra_days; /* specifies when sunday occurs in march */
    int  epact; /* age of the calendar moon at the beginning of the year */

    golden_number = eyear % 19 + 1;
    if (eyear > 1582)
    {
      century              = eyear / 100 + 1;
      gregorian_correction = (3 * century) / 4 - 12;
      clavian_correction   = (century - 16 - (century - 18) / 25) / 3;
      extra_days           = (5 * eyear) / 4 - gregorian_correction - 10;
      epact                = (11 * golden_number + 19 + clavian_correction -
                               gregorian_correction) % 30 + 1;
      if (((epact == 25) && (golden_number > 11)) || (epact == 24))
        epact = epact + 1;
    }
    else
    {
      extra_days = (5 * eyear) / 4;
      epact  = (11 * golden_number - 4) % 30 + 1;
    }

    *eday  = 44 - epact;
    if (*eday < 21)
      *eday = *eday + 30;
    *eday  = *eday + 7 - ((extra_days + *eday) % 7);

    if (*eday <= 31)
    {
      *emonth = 3;
    }
    else
    {
      *emonth = 4;
      *eday   = *eday - 31;
    }
  } /* easter1 */

/*

*/
PUBLIC  void easter2 (eyear,   eday, emonth)
  /* Fischer Lexikon Astronomie, p. 50:
     Algorithm of C.F. Gauá (1777-1855),
     for 1583 <= eyear <= 2299

     this seems to be the most concise algorithm
  */
  int  eyear; /* calculate Easter for this year */
  int *eday; /* day of Easter (1..29) */
  int *emonth; /* month of Easter (3 or 4) */
  { /* easter2 */
    int m, n, p, q, r, x, y, a, b, c, d, e;

    if (eyear <= 1699)  { m = 22; n = 2; } else
    if (eyear <= 1799)  { m = 23; n = 3; } else
    if (eyear <= 1899)  { m = 23; n = 4; } else
    if (eyear <= 2099)  { m = 24; n = 5; } else
    if (eyear <= 2199)  { m = 24; n = 6; } else
    if (eyear <= 2299)  { m = 25; n = 0; }
    a  = eyear % 19;
    b  = eyear %  4;
    c  = eyear %  7;
    d  = (19 * a + m) % 30;
    e  = (2 * b + 4 * c + 6 * d + n) % 7;

    *eday   = 22 + d + e;
    *emonth =  4;

    if (*eday <= 31)
      *emonth =  3;
    else
    if ((d == 28) && (e == 6) && (a > 10))
      *eday = 18;
    else
    if ((d == 29) && (e == 6))
      *eday = 19;
    else
      *eday = d + e - 9;
  } /* easter2 */

/*

*/
PUBLIC  void easter3 (eyear,   eday, emonth)
  /* from CHIP magazine, July 1986, p. 127
     for BASIC, all expressions (a / b) must be written as INT(A/B)

     similiar to Gauss' algorithm
  */
  int  eyear; /* calculate Easter for this year */
  int *eday; /* day of Easter (1..29) */
  int *emonth; /* month of Easter (3 or 4) */
  { /* easter3 */
    int p, q, r, x, y, a, b, c, d, e;

    p = eyear / 100;
    q = p / 3;
    r = p / 4;
    x = 15 + p - q - r;
    x = x - ((x / 30) * 30);
    y = p + 4 - r;
    y = y - ((y /  7) *  7);
    /* x = m, y = n in 'easter3' */
    a = eyear - ((eyear / 19) * 19);
    b = eyear - ((eyear /  4) *  4);
    c = eyear - ((eyear /  7) *  7);
    d = 19 * a + x;
    d = d - ((d / 30) * 30);
    e = 2 * b + 4 * c + 6 * d + y;
    e = e - ((e /  7) *  7);
    if ((22 + d + e) <= 31)
    {
      *eday   = 22 + d + e;
      *emonth = 3;
    }
    else
    if ((d == 28) && (e == 6) && (a > 10))
    {
      *eday   = 18;
      *emonth =  4;
    }
    else
    if ((d == 29) && (e == 6))
    {
      *eday   = 19;
      *emonth =  4;
    }
    else
    {
      *eday   = d + e - 9;
      *emonth = 4;
    }
  } /* easter3 */

/*---------------------------------------------------------

*/
PUBLIC  void easter_test ()
  /* call all 3 functions and test them against each other */
  { /* easter_test */
    int eyear;
    int eday1, emonth1;
    int eday2, emonth2;
    int eday3, emonth3;

    for (eyear = 1583; eyear <= 2299; eyear++)
    {
      easter1 (eyear,   & eday1, & emonth1);
      printf ("%4d: %2d.%02d.", eyear, eday1, emonth1);
      easter2 (eyear,   & eday2, & emonth2);
      printf ("     %2d.%02d.",        eday2, emonth2);
      easter3 (eyear,   & eday3, & emonth3);
      printf ("     %2d.%02d.",        eday3, emonth3);

      if ((emonth1 != emonth2) || (emonth1 != emonth3) ||
          (eday1 != eday2) || (eday1 != eday3))
      {
        printf ("-------> error");
      }
      printf ("\n");
    } /* for eyear */
  } /* easter_test */
/*

*/
PUBLIC  void calend_test ()
  /* call all calendar functions and test them */
  { /* calend_test */
    int  day, month, year;
    int  day2; /* another day for comparision */
    int  month2; /* another month */
    int  year2; /* another year */
    int  day_num; /* number of day in year */
    long julian; /* some Julian date */
    long julian2; /* another Julian date */

    for (year = 1995; year <= 2000; year ++)
    {
      for (month = 1; month <= 12; month ++)
      {
        day = 1;
        day_num = day_in_year (day, month, year);
        printf ("number of %d-%d-%d: %d\n", day, month, year, day_num);
        day_to_date (year, day_num, & day2, & month2);
        printf ("reversed: %d-%d-%d\n",     day2, month2,  year);
        if (day2 != day || month2 != month)
          printf ("---------------------------> error!\n");
      } /* for month */
    } /* for year */

    printf ("\nweek days\n");
    for (day = 17; day <= 23; day ++)
    {
      printf ("%d\n", week_day (day, 7, 1995));
    }

    year = 1994;
    printf ("%d:\n", year);
    for (day_num = 1; day_num <= 365; day_num ++)
    {
      day_to_date (year, day_num,   & day2, & month2);
      printf ("%d=%d ", day2, week_in_year (day2, month2, year));
    } /* for day */
    printf ("\n");

    year = 1670;
    julian = julian_date (1, 1, year);

    for (year = year; year <= 2200; year ++)
    {
      printf ("Julian date of 1-Jan-%d = %ld\n", year, julian);
      gregorian_date (julian, & day2, & month2, & year2);
      if (day2 != 1 || month2 != 1 || year2 != year)
        printf ("error in 'gregorian_date': %d-%d-%d\n",
          day2, month2, year2);
      julian2 = julian_date (31, 12, year);
      julian += day_in_year (31, 12, year);
      if (julian2 != julian - 1)
        printf ("----------------------------> error: %ld != %ld\n",
          julian, julian2);
    } /* for year */

    easter_test ();
  } /* calend_test */

#define  MAX_DESCR 32
PRIVATE  struct {
  char work;  /* ' ' for working day, 'F' for holiday */
  char pamt;  /* parament colors */
#define WHITE  '0'
#define RED    '1'
#define GREEN  '2'
#define VIOLET '3'
#define PUNDEF ' ' /* inherits color from previous day */
#define BLACK  '7'
  char line;  /* printing line for a day, '0' = highest */
  int  weekd; /* 1 = Monday, 7 = Sunday */
  int  month; /* month */
  int  day; /* day in month */
  char descr[MAX_DESCR]; /* description of that day */
  } cal[367]; /* calendar, [0] never used */

/*

*/
PUBLIC   void church_year (year, church)
  /* print the variable holidays of a year */
  int  year; /* print holy days of this year */
  int  church; /* EVANGELIC, CATHOLIC ... */
  { /* church_year */
    int  day2; /* another day for comparision */
    int  month2; /* another month */
    int  day_num; /* number of day in year */
    int  eday, emonth; /* Easter date */
    int  eadn; /* number of Easter Sunday */
    int  he24; /* number of 24-Dec */
    int  day_31_12; /* 365 or 366 */
    int  adv1; /* number of 1st Advent */
    int  epi1; /* number of 1st Sunday after Epiphanias */
    char text[MAX_DESCR]; /* for dynamical descriptions */
    char cur_pamt; /* current parament color */

#define SETX(dn,tx) /* set text to current day */\
    day2 = dn;\
    strcpy (cal[day2].descr, tx)
#define SETC(dn,tx) /* set text to current day, -c + -e */\
    day2 = dn;\
    if (church != KATHOLISCH)\
    strcpy (cal[day2].descr, tx)
#define SEMD(day, mon, tx) /* set text in month day */\
    day2 = day_in_year (day, mon, year);\
    strcpy (cal[day2].descr, tx);
#define FREE 'f'
#define SUN  's'
#define SENW /* set day to non-working */\
    cal[day2].work = SUN;
#define SECO(color_this, color_next) /* set parament color */\
    cal[day2    ].pamt = color_this;\
    cal[day2 + 1].pamt = color_next;
    /*----------------------------------*/

    /* the fixpoint days for calendar computation */
    day_31_12 = day_in_year (31, 12, year);
    he24 = day_31_12 - 7;
    adv1 = he24 - (week_day (24, 12, year) % 7) /* 4. Advent */ - 21;
    easter2 (year, & eday, & emonth);
    /* Ostern am 1. Sonntag nach dem Vollmond an oder nach dem
       21. Maerz (= Fruehlingsanfang) */
    eadn = day_in_year (eday, emonth, year);
    epi1 = 13 - week_day (6, 1, year);
    if (epi1 == 6)
      epi1 += 7;

    for (day_num = 1; day_num <= day_31_12; day_num ++)
    { /* preset the calendar */
      cal[day_num].work = ' ';
      cal[day_num].pamt = PUNDEF; /* inherits color from previous day */
      cal[day_num].line = '0'; /* default = 1st line */
      day_to_date (year, day_num, & cal[day_num].day, & cal[day_num].month);
      cal[day_num].weekd =
      week_day (cal[day_num].day, cal[day_num].month, year);
      SETX (day_num, "");
    } /* for day_num, preset */

    if (epi1 >= 8)
      SETC (epi1 - 7, "2. So. n. Weihn.");
    SEMD ( 1, 1,     "Neujahr"); SENW;
    SECO (WHITE, PUNDEF);

    switch (church)
    {
    case CATHOLIC:
    case KATHOLISCH:
      SEMD ( 6, 1,     "Hl. Drei Könige"); SENW;
      SECO (WHITE, GREEN);
      for (day_num =  0; day_num <= 28; day_num += 7)
      { /* Sonntage nach Epiphanias */
        sprintf (text, "%d. So.i.Jkrs.", day_num / 7 + 1);
        SETX (epi1 + day_num, text);
      } /* while i.Jkrs. */
      break;
    default:
    case EVANGELIC:
      SEMD ( 6, 1,     "Epiphanias"); SENW;
      SECO (WHITE, GREEN);
      for (day_num =  0; day_num <= 28; day_num += 7)
      { /* Sonntage nach Epiphanias */
        sprintf (text, "%d. So.n.Epiph.", day_num / 7 + 1);
        SETX (epi1 + day_num, text);
      } /* while Epiphanias */

      SETX (eadn - 70, "Letzter So.n.Epiph.");
      SECO (WHITE, GREEN);
      break;
    } /* EVANGELIC */
    SETC (eadn - 63, "Septuagesimae");
    SETC (eadn - 56, "Sexagesimae");
    SETC (eadn - 49, "Estomihi");
    SETX (eadn - 48, "Rosenmontag");
    SETX (eadn - 47, "Fastnacht");
    SETX (eadn - 46, "Aschermittwoch");
    SECO (VIOLET, VIOLET);
    SETC (eadn - 42, "Invokavit");
    SETC (eadn - 35, "Reminiszere");
    SETC (eadn - 28, "Okuli");
    SETC (eadn - 21, "Laetare");
    SETC (eadn - 14, "Judika");
    SETX (eadn -  7, "Palmsonntag");
    SETX (eadn -  3, "Gründonnerstag");
    SECO (WHITE, BLACK);
    SETX (eadn -  2, "Karfreitag"); SENW;
    SECO (BLACK, BLACK);
    SETX (eadn +  0, "Ostersonntag");
    SECO (WHITE, WHITE);
    SETX (eadn +  1, "Ostermontag"); SENW;
    switch (church)
    {
    case CATHOLIC:
    case KATHOLISCH:
      SETX (eadn +  7, "Weißer Sonntag");
      break;
    default:
    case EVANGELIC:
      SETX (eadn +  7, "Quasimodogeniti");
      break;
    }
    SETC (eadn + 14, "Misericordias Domini");
    SETC (eadn + 21, "Jubilate");
    SETC (eadn + 28, "Kantate");
    SETC (eadn + 35, "Rogate");
    SEMD ( 1,  5,    "Maifeiertag"); SENW;
    SETX (eadn + 39, "Christi Himmelfahrt"); SENW;
    SETC (eadn + 42, "Exaudi");
    SETX (eadn + 49, "Pfingstsonntag");
    SECO (RED,RED     );
    SETX (eadn + 50, "Pfingstmontag"); SENW;
    SECO (RED, RED    );

    SETX (eadn + 56, "Trinitatis");
    SECO (WHITE, GREEN);
    for (day_num =  7; day_num <= 24 * 7; day_num += 7)
    { /* Sonntage nach Trinitatis */
      sprintf (text, "%d. So. n. Trinitatis", day_num / 7);
      SETX (eadn + 56 + day_num, text);
    } /* for Trinitatis */

    SETX (eadn + 60, "Fronleichnam"); SENW;

    day_num = day_in_year (1, 10, year);
    while (cal[day_num].weekd != 7)
      day_num ++; /* will stop at 1st Sunday in October */
    SETX (day_num,   "Erntedank");

    SEMD (24,  6,    "Johannis");
    SECO (WHITE, GREEN);
    SEMD (29,  9,    "Michaelis");
    SECO (WHITE, GREEN);

    SEMD ( 3, 10,    "Tag d. Wiedervereinigung"); SENW;
    SEMD (31, 10,    "Reformationsfest");
    SECO (RED, GREEN);
    SEMD ( 1, 11,    "Allerheiligen"); SENW;
    switch (church)
    {
    case CATHOLIC:
    case KATHOLISCH:
      SEMD ( 2, 11,    "Allerseelen");
      SEMD (15,  8,    "Mariä Himmelfahrt");
      SEMD ( 8, 12,    "Mariä Empfängnis");
      break;
    default:
    case EVANGELIC:
      SEMD (31, 10,    "Reformationstag");
      break;
    }
    SETC (adv1 - 21, "3.letzter So. im Kj.");
    SETX (adv1 - 14, "Volkstrauertag");
    SETX (adv1 - 11, "Buß- und Bettag");
    SECO (VIOLET, GREEN);
    switch (church)
    {
    case CATHOLIC:
      SETX (adv1 - 7,  "Totensonntag");
      break;
    default:
    case EVANGELIC:
      SETX (adv1 -  7, "Ewigkeitssonntag");
    }
    SECO (GREEN, VIOLET);
    SEMD ( 6, 12,    "Nikolaus");
    /* Buss- und Bettag am Mittwoch vor dem Totensonntag= Sonntag vor
       dem 1. Advent; 4. Advent = Sonntag vor oder am 24.12.
       z.B. 24.12.2000 = 4. Advent
    */
    SETX (adv1 +  0, "1. Advent");
    SETX (adv1 +  7, "2. Advent");
    SETX (adv1 + 14, "3. Advent");
    SETX (adv1 + 21, "4. Advent");
    if  (adv1 + 28 <= day_31_12)
    {
      SETX (adv1 + 28, "So.n.Weihnachten");
    }
    SEMD (24, 12,    "Heiliger Abend");
    SEMD (25, 12,    "1. Weihnachtsfeiertag"); SENW;
    SECO (WHITE, PUNDEF);
    SEMD (26, 12,    "2. Weihnachtsfeiertag"); SENW;
    SEMD (31, 12,    "Silvester");

    /* postprocess sundays and colors */
    cur_pamt = PUNDEF;
    for (day_num = 1; day_num <= day_31_12; day_num ++)
    { /* define sundays and free days in the calendar */
      if (cal[day_num].pamt != PUNDEF)
        cur_pamt = cal[day_num].pamt;

      switch (cal[day_num].weekd)
      {
      case 6: /* Sa */
        if (cal[day_num].work != SUN)
          cal[day_num].work = FREE;
        break;
      case 7: /* So */
        cal[day_num].work = SUN;
        break;
      default:
        break;
      } /* switch set working status */

      if (cal[day_num].descr[0] != '\0')
      { /* Sunday or non-blank */
        cal[day_num].line = '1';
      } /* if Sunday or non-blank */
      printf ("|%c%c|%c|%-2s|%2d|%02d|%04d|%-s| |\n",
        cal[day_num].work,
        cur_pamt,
        cal[day_num].line,
        wd_name[cal[day_num].weekd - 1],
        cal[day_num].day, cal[day_num].month, year,
        cal[day_num].descr);
    } /* for day_num, preset */

  } /* church_year */

PUBLIC    void holy_days (year)
  /* print the variable holidays of a year */
  int  year; /* print holy days of this year */
  { /* holy_days */
    int  day2; /* another day for comparision */
    int  month2; /* another month */
    int  day_num; /* number of day in year */
    int  eday2, emonth2; /* Easter date */
    int  wd24; /* week day of 24-Dec */

    easter2 (year, & eday2, & emonth2);
    printf ("%d:\n", year);
    day_num = day_in_year (eday2, emonth2, year);

    /* Ostersonntag ist der 1. Sonntag nach dem Vollmond an oder nach dem
       21. Maerz (Fruehlingsanfang) */
    printf ("Ostersonntag        %2d.%02d.\n", eday2, emonth2);

    /* Rosenmontag = Ostermontag - 7 Wochen, Fastenzeit = 6.5 Wochen */
    day_to_date (year, day_num - 47, & day2, & month2);
    /* Shrove Tuesday */
    printf ("Faschingsdienstag   %2d.%02d.\n", day2, month2);

    /* Himmelfahrt am Donnerstag in der 6. Woche nach Ostern */
    day_to_date (year, day_num + 39, & day2, & month2);
    /* Ascension */
    printf ("Christi Himmelfahrt %2d.%02d.\n", day2, month2);

    /* Pfingsten 7 Wochen nach Ostern */
    day_to_date (year, day_num + 49, & day2, & month2);
    /* Whitsunday, Pentecost */
    printf ("Pfingsten           %2d.%02d.\n", day2, month2);

    /* Fronleichnam am Donnerstag in der 8. Woche nach Ostern */
    day_to_date (year, day_num + 60, & day2, & month2);
    /* Corpus Christi (Day) */
    printf ("Fronleichnam        %2d.%02d.\n", day2, month2);

    /* Buss- und Bettag am Mittwoch vor dem Totensonntag = Sonntag vor
       dem 1. Advent; 4. Advent = Sonntag vor oder am 24.12.
    */
    wd24 = week_day (24, 12, year);
    /* day of repentance and prayer */
    printf ("Buss- und Bettag    %2d.%02d.\n", 22 - wd24, 11);

    /* Christmas Eve */
    printf ("Heiligabend am      %s\n", wd_name[wd24 - 1]);
  } /* holy_days */

/*--------------------------------------------------------

*/
PUBLIC  int main (argc, argv)
  int  argc; /* number of arguments */
  char *argv[]; /* argument strings */
  { /* main */
    int  day, month, year;
    int  iarg; /* index for arguments */

    if (argc <= 1)
    { /* no parameters - test routines */
      calend_test ();
    } /* test routines */
    else
    { /* with >= 1 parameter */
      iarg = 1;
      if (isdigit (argv[iarg][0]))
      {
        sscanf (argv[iarg], "%d", & year);
        holy_days (year);
      }
      else
      if (argv[iarg][0] == '-')
      { /* with option */
        sscanf (argv[iarg + 1], "%d", & year);
        switch (tolower (argv[iarg][1]))
        {
        default:
        case 'h':
          holy_days (year);
          break;
        case 'c':
          church_year (year, CATHOLIC);
          break;
        case 'k':
          church_year (year, KATHOLISCH);
          break;
        case 'e':
          church_year (year, EVANGELIC);
          break;
        } /* switch option letter */
      } /* with option */
    } /* with parameter(s) */
    return 0;
  } /* main */
/*--------------------------------------------------------*/
#ifdef never

Letzte Änderung: 16.02.2001
Bitte richten Sie Fragen oder Kommentare an: <punctum@punctum.com>, Dr. Georg Fischer.

#endif /* never */