From decwrl!ucbvax!tut.cis.ohio-state.edu!rutgers!aramis.rutgers.edu!dartagnan.rutgers.edu!mcgrew Sat May 27 20:07:12 PDT 1989 Article 13 of comp.sources.sun: Path: decwrl!ucbvax!tut.cis.ohio-state.edu!rutgers!aramis.rutgers.edu!dartagnan.rutgers.edu!mcgrew From: mcgrew@dartagnan.rutgers.edu (Charles Mcgrew) Newsgroups: comp.sources.sun Subject: v01i012: Calendar/planning tool: Part 03/09 Message-ID: Date: 27 May 89 21:08:47 GMT Organization: Rutgers Univ., New Brunswick, N.J. Lines: 2122 Approved: mcgrew@aramis.rutgers.edu Submitted-by: Bill Randle Posting-number: Volume 1, Issue 12 Archive-name: calentool/part03 #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # datelib.c # day.cursor # event.c # event.h # This archive created: Sat May 27 13:11:31 1989 export PATH; PATH=/bin:$PATH echo shar: extracting "'datelib.c'" '(44349 characters)' if test -f 'datelib.c' then echo shar: will not over-write existing file "'datelib.c'" else sed 's/^ X//' << \SHAR_EOF > 'datelib.c' X/* X * $Header: datelib.c,v 2.1 89/05/09 14:18:52 billr Exp $ X * X * datelib.c - Calendar (date) computation library X * X * R. P. C. Rodgers, UCSF, November 1988 X * (with thanks to Greg Couch, Conrad Huang, and Dave Yee for their helpful X * suggestions) X * X * Copyright 1988, 1989 R. P. C. Rodgers, All Rights Reserved X * Permission is granted by the author for use of this code under the following X * conditions: 1) improvements and corrections to this code are shared with the X * author; 2) the code is made freely available to anyone requesting it; 3) the X * code is not used for any profit-making venture without the express X * permission of the author; and, 3) all copies of the code will preserve the X * above authorship and copyright information and this notice. X * X * (requires math library) X * X * Source of formulae: X * X * 1) Schocken, Wolfgang Alexander X * The calculated confusion of calendars; puzzles in Christian, Jewish and X * Moslem calendars. X * 1st Ed. X * Vantage Press X * New York X * 1976 X * X * 2) Meeus, Jean X * Astronomical Formulae for Calculators X * Monografieen over Astronomie en Astrofysica X * Volkssterrenwacht Urania V.Z.W. X * Mattheessensstraat 62, B 2540 Hove, Belgium X * Vereniging voor Sterrenkunde V.Z.W. X * Ringlaan 3, B 1180 Brussel, Belgium X * Vol. 4 X * Derde Druk X * October 1980 X * (3rd edition of 1985 available from Willmann-Bell, address below) X * (formulae for Easter, Julian and Gregorian date formation, and X * solstices/equinoxes) X * X * 3) Assorted contributions to the Hewlett-Packard HP-41C Software Library X * X * In his 1987 Sun program "moontool," John Walker (Autodesk, Sausalito, CA) X * mentions several other potentially useful references: X * X * 4) Pierre Bretagnon and Jean-Louis Simon X * Planetary Programs and Tables from -4000 to +2800 X * Willmann-Bell X * 1986 X * (for utmost accuracy in planetary computations) X * X * 5) Eric Burgess X * Celestial BASIC X * Revised Edition X * Sybex X * 1985 X * (cookbook oriented, many algorithms hard to dig out of turgid BASIC) X * X * Many of these references can be obtained from Willmann-Bell, P.O. Box X * 35025, Richmond, VA 23235, USA. Phone: (804) 320-7016. In addition X * to their own publications, they stock most of the standard references X * for mathematical and positional astronomy. X * X * NOTES: X * check ranges on days (0-365) X * islamic new year and jewish dates not thoroughly tested X * X */ X X#include "ct.h" /* for the NO_HOLIDAYS #define */ X X#include /* for NULL */ X#include X Xdouble julian_day(); X X#ifndef NO_HOLIDAYS Xextern char *malloc(); Xdouble easter_offset(), passover_offset(); X Xstatic char *monthname[] = { X "January", "February", "March", "April", "May", X "June", "July", "August", "September", X "October", "November", "December" }; Xstatic char *dayname[] = { X "Sunday", "Monday", "Tuesday", "Wednesday", X "Thursday", "Friday", "Saturday" }; Xstatic char timebuf[16]; X X/* X * date_string: X * Return date string of form: "Monday 12 December 1988" X * given day of week (0-6), day (1-31), month (1-12), year X */ Xchar * Xdate_string(day_of_week, day, month, year) X double day; X int day_of_week, month, year; X{ X char *date; X X date = (char *) malloc(81 * sizeof(char)); X if (date == NULL) X err_rpt("out of memory", FATAL); X (void) sprintf(date, "%s %d %s %d", X dayname[day_of_week], (int) day, monthname[--month], year); X return date; X} X X/* X * date_string_2: X * Return date string of form: "Monday 12 December 1988 (NYEAR)" X * given day of week (0-6), day (1-31), month (1-12), year, and alternate X * (that is, non-Gregorian) year, NYEAR X */ Xchar * Xdate_string_2(day_of_week, day, month, year, nyear) X double day; X int day_of_week, month, nyear, year; X{ X char *date; X X date = (char *) malloc(81 * sizeof(char)); X if (date == NULL) X err_rpt("out of memory", FATAL); X (void) sprintf(date, "%s %d %s %d (%d)", X dayname[day_of_week], (int) day, monthname[--month], X year, nyear); X return date; X} X X/* X * date_time_string: X * Return date/time string of form: "10:42 Monday 12 December 1988" X * given hour (0-24), minute (0-59), day of week (0-6), day (1-31), X * month (1-12), year X */ Xchar * Xdate_time_string(hour, min, day_of_week, day, month, year) X double day; X int day_of_week, hour, min, month, year; X{ X char *date; X X date = (char *) malloc(81 * sizeof(char)); X if (date == NULL) X err_rpt("out of memory", FATAL); X (void) sprintf(date, "%02d:%02d %s %d %s %d", X hour, min, dayname[day_of_week], (int) day, X monthname[--month], year); X return date; X} X X/* X * election_day: X * Compute date of Election Day given year (1584-9999) X * Election day is defined as the first Tuesday following the first X * Monday in November. X */ Xdouble Xelection_day(year) X int year; X{ X double day, nth_mday_of_month(); X X /* find first Tuesday in Nov. */ X day = nth_mday_of_month(1, 2, 11, year); X /* if it's the first day of the month then Election day is next week */ X if (day == 1.) X day = 8.; X return julian_day(day, 11, year); X} X X/* X * dday2: X * Compute dday2 for various holiday routines given x value, year (>1583) X */ Xdday2(x, year) X int x, year; X{ X int atmp, btmp; X X atmp = 1.25 * year; X btmp = year / 100; X btmp = 0.75 * (1 + btmp); X return (x + atmp - btmp) % 7; X} X#endif /* NO_HOLIDAYS */ X X/* X * days_remaining_in_year: X * Compute remaining days of year (0-366) X * given day (1-31), month (1-12), year (1901-2009) X */ Xdays_remaining_in_year(day, month, year) X double day; X int month, year; X{ X int length_of_year(), day_of_year(); X X return length_of_year(year) - day_of_year(day, month, year); X} X X/* X * length_of_year: X * Compute days in year (0-366) X * given year (1901-2009) X */ Xlength_of_year(year) X int year; X{ X int ylength; X X if ((year % 400) == 0) X ylength = 366; X else if ((year % 100) == 0) X ylength = 365; X else if ((year % 4) == 0) X ylength = 366; X else X ylength = 365; X return ylength; X} X X/* X * get_day_of_week: X * Compute day of week (0-6 for Sunday-Saturday) X * given day (1-31), month (1-12), year (1901-2009) X */ Xget_day_of_week(day, month, year) X double day; X int month, year; X{ X int atmp; X X atmp = julian_day(day, month, year) + 1.5; X return atmp % 7; X} X X/* X * day_ of_year: X * Compute day of year (0-366) X * given day (1-31), month (1-12), year (1901-2009) X */ Xday_of_year(day, month, year) X double day; X int month, year; X{ X return (int) julian_day(day, month, year) X - (int) julian_day(0.0, 1, year); X} X X/* X * julian_day: X * Compute Julian day (>=1) X * given day (1-31), month (1-12), year (1901-2009) X * X * Notes: The Gregorian reform is taken into account (that is, the day X * following 4 October 1582 is 15 October 1582; dates on this latter day or X * later are said to be in the Gregorian calendar). B.C. years are counted X * astronomically (the year prior to year 1 is year 0). The Julian day X * begins at GMT noon (the day is expressed in floating point). X * Example: to obtain Julian day for 4 Jul 1979: julian_day(4.0, 7, 1979) X */ Xdouble Xjulian_day(day, month, year) X double day; X int month, year; X{ X int atmp, btmp, monthp, yearp; X double ctmp; X X if (month > 2) { X monthp = month + 1; X yearp = year; X } X else { X monthp = month + 13; X yearp = year - 1; X } X if ((year > 1582) || (year == 1582 && month >= 10) X || (year == 1582 && month ==10 && day >= 15)) { X atmp = year / 100; X btmp = 2 - atmp + (atmp / 4); X } X else X btmp = 0; X atmp = 365.25 * yearp; X ctmp = atmp; X atmp = 30.6001 * monthp; X ctmp = ctmp + atmp; X return ctmp + day + 1720994.5 + btmp; X} X X#ifndef NO_HOLIDAYS X/* X * corrected_julian_day: X * Correct Julian day (>=1) for conversion from JULIAN CALENDAR X * to GREGORIAN CALENDAR. X */ Xdouble Xcorrected_julian_day(jday) X double jday; X{ X double day; X int atmp, btmp, month, year; X X gregorian_date(&day, &month, &year, jday); X atmp = year / 100; X btmp = ((3 * atmp) - 5) / 4; X return julian_day(day, month, year) + btmp; X} X X/* X * gregorian_date: X * Return pointers to day (1-31), month (1-12), year (1901-2009), X * given Julian day (>=0) X * X * Notes: The Gregorian reform is taken into account (that is, the day X * following 4 October 1582 is 15 October 1582; dates on this latter day or X * later are said to be in the Gregorian calendar). B.C. years are counted X * astronomically (the year prior to year 1 is year 0). The Julian day X * begins at GMT noon. The Julian day can be expressed in X * floating point below to get a day result with decimal places. This method X * is valid only for positive Julian day numbers. X */ Xgregorian_date(p_day, p_month, p_year, jday) X int *p_month, *p_year; X double *p_day, jday; X{ X int atmp, btmp, ctmp, dtmp, etmp, gtmp, ztmp; X double ftmp; X X ztmp = jday + 0.5; X ftmp = (jday + 0.5) - ztmp; X if (ztmp >= 2299161) { X gtmp = (ztmp - 1867216.25) / 36524.25; X ctmp = gtmp / 4; X atmp = ztmp + 1 + gtmp - ctmp; X } X else X atmp = ztmp; X btmp = atmp + 1524; X ctmp = (btmp - 122.1) / 365.25; X dtmp = 365.25 * ctmp; X etmp = ((btmp - dtmp) / 30.6001); X ztmp = 30.6001 * etmp; X *p_day = btmp - dtmp - ztmp + ftmp; X if (etmp > 13.5) X *p_month = etmp - 13; X else X *p_month = etmp - 1; X if (*p_month > 2.5) X *p_year = ctmp - 4716; X else X *p_year = ctmp - 4715; X} X X/* X * mdays_between_dates: X * Compute number of mdays between two dates (exclusive: don't count the X * days themselves) given day of week (0-6, O for Sunday), X * two sets of day (1-31), month (1-12), year (1583-9999) X */ Xmdays_between_dates(day_of_week, day1, month1, year1, day2, month2, year2) X int day_of_week, month1, year1, month2, year2; X double day1, day2; X{ X return wday(day_of_week, day2, month2, year2) X - wday(day_of_week, day1, month1, year1); X} X X/* X * nth_mday_of_month: X * Compute nth m-day of the month (1-31) X * given n (1-5), day of week (0-6, 0 for Sunday), month (1-12), X * year (1583-9999) X */ Xdouble Xnth_mday_of_month(n, day_of_week, month, year) X int day_of_week, month, n, year; X{ X int atmp, btmp, ctmp, dtmp, etmp, ftmp, tmonth, tyear; X X if (month > 2) { X tmonth = month + 1; X tyear = year; X } X else { X tmonth = month + 13; X tyear = year - 1; X } X atmp = 2.6 * tmonth; X btmp = 1.25 * tyear; X ctmp = (tyear / 100) - 7; X dtmp = 0.75 * ctmp; X etmp = (day_of_week - atmp - btmp + dtmp) % 7; X if (etmp == 0) X ftmp = 7; X else X ftmp = etmp; X return (double) (ftmp + (n * 7)); X} X X/* X * years_date_is_mday: X * Compute year(s) for which a given date is an m-day X * given starting year, ending year, X * day of week (0-6, 0 for Sunday), day, and month X * algorithm said to be valid for 1 Mar 1900 to 28 Feb 2100. X */ Xyears_date_is_mday(day_of_week, day, month, start_year, end_year, yearlist, X number_of_years) X int day_of_week, end_year, month, *number_of_years, yearlist[], X start_year; X double day; X{ X int diff, index, year, tdow; X static int augment[] = {6, 11, 6, 5}; X X *number_of_years = 0; X if (start_year > end_year) return -1; X for (year = start_year; year <= end_year; year++ ) { X tdow = get_day_of_week(day, month, year); X if (tdow == day_of_week) { X yearlist[(*number_of_years)++] = year; X } X if (*number_of_years == 2 || *number_of_years == 3) { X diff = yearlist[*number_of_years] X - yearlist[*number_of_years - 1]; X if (diff == 5) { X year++; X index = 0; X break; X } X else if (diff == 11) { X year++; X index = 2; X break; X } X } X } X for ( ; year <= end_year; year++ ) { X yearlist[(*number_of_years + 1)] = X yearlist[*number_of_years] + augment[index++ % 4]; X (*number_of_years)++; X } X return 0; X} X X/* X * weekdays_between_dates: X * Compute weekdays between any two dates X * given two sets of day (1-31), month (1-12), year (1901-2009) X */ Xweekdays_between_dates(day1, month1, year1, day2, month2, year2) X int month1, month2, year1, year2; X double day1, day2; X{ X return wday2(day2, month2, year2) - wday2(day1, month1, year1); X} X X/* X * wday: X * Compute wday for mdays_between_dates routine X * given day of week, day, month, year X */ Xwday(day_of_week, day, month, year) X int day_of_week, month, year; X double day; X{ X int atmp, btmp, ctmp, dtmp; X X atmp = dday(day, month, year) - day_of_week; X btmp = atmp / 7; X ctmp = atmp % 7; X dtmp = 0.11 * ctmp + 0.9; X return btmp + (0.5 * dtmp); X} X X/* X * wday2: X * Compute wday2 for weekdays_between_dates routine X * given day, month, year X */ Xwday2(day, month, year) X int month, year; X double day; X{ X int atmp, btmp, ctmp, dtmp; X X atmp = dday(day, month, year); X btmp = atmp / 7; X ctmp = atmp % 7; X dtmp = 1.801 * ctmp; X return (5 * btmp) + (0.5 * dtmp); X} X X/* X * dday: X * Compute dday for other routines X * given day (1-31), month (1-12), year (1901-2009) X */ Xdday(day, month, year) X int month, year; X double day; X{ X int atmp, btmp, ctmp, dtmp, tmonth, tyear; X X if (month > 2) { X tmonth = month + 1; X tyear = year; X } X else { X tmonth = month + 13; X tyear = year - 1; X } X atmp = tyear / 100; X btmp = 0.75 * (atmp - 7); X ctmp = 365.25 * tyear; X dtmp = 30.6001 * tmonth; X return (int) day - btmp + ctmp + dtmp; X} X X/* X * vernal_equinox: X * Compute Julian day for Vernal (March) Equinox given year (1901-2009) X */ Xdouble Xvernal_equinox(year) X int year; X{ X double solstice_equinox_exact(); X X return solstice_equinox_exact(0, year); X} X X/* X * summer_solstice: X * Compute Julian day for Summer Solstice (June) given year (1901-2009) X */ Xdouble Xsummer_solstice(year) X int year; X{ X double solstice_equinox_exact(); X X return solstice_equinox_exact(1, year); X} X X/* X * autumn_equinox: X * Compute Julian day for Autumnal (September) Equinox given year (1901-2009) X */ Xdouble Xautumn_equinox(year) X int year; X{ X double solstice_equinox_exact(); X X return solstice_equinox_exact(2, year); X} X X/* X * winter_solstice: X * Compute Julian day for Winter (December) Solstice given year (1901-2009) X */ Xdouble Xwinter_solstice(year) X int year; X{ X double day, jday; X int month, nyear; X double solstice_equinox_exact(); X X jday = solstice_equinox_exact(3, year); X gregorian_date(&day, &month, &nyear, jday); X if (nyear == year) X return jday; X else X return solstice_equinox_exact(3, (year + 1)); X} X X/* X * solstice_equinox__exact: X * Compute more precise date for Solstice/Equinox X * given code (1-4, 1 for Vernal Equinox), year (1901-2009) X */ Xdouble Xsolstice_equinox_exact(code, year) X int code, year; X{ X int count; X X double corr, jday_app; X double solstice_equinox_approx(), solstice_equinox_correction(); X X /* compute first approximation to Julian day */ X jday_app = solstice_equinox_approx(code, year); X /* iteratively recompute corrected Julian day */ X for(count = 0; count < 15; count++) { X corr = solstice_equinox_correction(jday_app, code); X jday_app += corr; X if (fabs(corr) < 0.00001) X break; X } X return jday_app; X} X X/* X * solstice_equinox_correction: X * Compute correction for Solstice/Equinox Julian day X * approximate Julian day, code (1-4, 1 for Vernal Equinox) X */ Xdouble Xsolstice_equinox_correction(jday, code) X int code; X double jday; X{ X double apparent_longitude(), sin_degrees(); X X return(58.0 * sin_degrees((code * 90.0) - apparent_longitude(jday))); X} X X/* X * apparent_longitude: X * Compute apparent longitude (true equinox) of Sun for X * Solstice/Equinox given approximate Julian day X */ Xdouble Xapparent_longitude(jday) X double jday; X{ X double btmp, ctmp, dtmp, etmp, ftmp; X double sin_degrees(); X X btmp = (jday - 2415020.0) / 36525.0; /* time in Julian centuries: */ X /* epoch 0.5 January 1900 */ X ctmp = 279.69668 + (36000.76892 * btmp) /* geometric mean longitude */ X + (0.0003025 * btmp * btmp); /* (mean equinox of the date) */ X dtmp = 358.47583 + (35999.04975 * btmp) /* mean anomaly of Sun */ X + (0.00015 * btmp * btmp) X + (0.0000033 * btmp * btmp * btmp); X etmp = (1.919460 - (0.004789 * btmp) /* Sun's eqn of the center */ X - (0.000014 * btmp)) * sin_degrees(dtmp) X + (0.020094 - (0.0001 * btmp)) * sin_degrees(2 * dtmp) X + 0.000293 * sin_degrees(3 * dtmp); X ftmp = ctmp + etmp; /* Sun's true longitude */ X return ftmp - 0.00569 /* app. long. of Sun */ X - 0.00479 * sin_degrees(259.18 /* (true equinox of the date) */ X - (1934.142 * btmp)); X} X X/* X * sin_degrees: X * Compute sin for argument in degrees X */ Xdouble Xsin_degrees(degrees) X#define PI_CORR 0.01745329252 /* pi / 180 */ X double degrees; X{ X return sin(degrees * PI_CORR); X} X X/* X * solstice_equinox_approx: X * Compute approximate date for Solstice/Equinox X * given code (1-4, 1 for Vernal Equinox), year (1901-2009) X */ Xdouble Xsolstice_equinox_approx(code, year) X int code, year; X{ X return (365.2422 * (year + (code / 4))) + 1721141.3; X} X X/* X * easter: X * Return Julian date for Easter, given year (1901-2009) X * X * Offered in the book of Meeus, which cites: X * X * 1) Spencer Jones X * General Astronomy X * 1922 X * pg. 73-74 X * X * 2) Journal of the British Astronomical Association X * Vol. 8 X * Pg. 91 X * Dec. 1977 X * (which attributes method to Butcher's Ecclesiastical Calendar of 1876) X * X * Method valid for all dates in the Gregorian calendar X * (from 15 October 1583 on) X */ Xdouble Xeaster(year) X int year; X{ X double day; X int atmp, btmp, ctmp, dtmp, etmp, ftmp, X gtmp, htmp, itmp, ktmp, ltmp, mtmp; X int month; X X atmp = year % 19; X btmp = year / 100; X ctmp = year % 100; X dtmp = btmp / 4; X etmp = btmp % 4; X ftmp = (btmp + 8) / 25; X gtmp = (btmp - ftmp + 1) / 3; X htmp = ((19 * atmp) + btmp - dtmp - gtmp + 15) % 30; X itmp = ctmp / 4; X ktmp = ctmp % 4; X ltmp = (32 + (2 * etmp) + (2 * itmp) - htmp - ktmp) % 7; X mtmp = (atmp + (11 * htmp) + (22 * ltmp)) / 451; X month = (htmp + ltmp - (7 * mtmp) + 114) / 31; X day = ((htmp + ltmp - (7 * mtmp) + 114) % 31) + 1; X return julian_day(day, month, year); X} X X/* X * first_sunday_advent: X * Christian holidays: compute Julian day for First Sunday in Advent X * (closest Sunday to St. Andrew's day, the last day in November) X * given year (>1583) X */ Xdouble Xfirst_sunday_advent(year) X int year; X{ X int atmp; X X atmp = get_day_of_week(30.0, 11, year); X if (atmp <= 3) { X return julian_day((30.0 - (double) atmp), 11, year); X } X else { X return julian_day(30.0, 11, year) + (7 - atmp); X } X} X X/* X * easter_offset: X * Christian holidays: compute Julian day as offset from Easter X * given year (>1583) X */ Xdouble Xeaster_offset(offset, year) X double offset; X int year; X{ X double easter(); X X return easter(year) + offset; X} X X/* X * septuagesima: X * Christian holidays: compute Julian day for Septuagesima Sunday X * (Third Sunday before Lent) X * given year (>1583) X */ Xdouble Xseptuagesima(year) X int year; X{ X return easter_offset(-63.0, year); X} X X/* X * sexagesima: X * Christian holidays: compute Julian day for Sexagesima Sunday X * (Second Sunday before Lent) X * given year (>1583) X */ Xdouble Xsexagesima(year) X int year; X{ X return easter_offset(-56.0, year); X} X X/* X * quinquagesima: X * Christian holidays: compute Julian day for Quinquagesima (Shrove) Sunday X * (Sunday before Lent begins on Ash Wednesday) X * given year (>1583) X */ Xdouble Xquinquagesima(year) X int year; X{ X return easter_offset(-49.0, year); X} X X/* X * shrove_monday: X * Christian holidays: compute Julian day for Shrove Monday X * (Two days before Lent begins on Ash Wednesday) X * given year (>1583) X */ Xdouble Xshrove_monday(year) X int year; X{ X return easter_offset(-48.0, year); X} X X/* X * shrove_tuesday: X * Christian holidays: compute Julian day for Shrove Tuesday X * (Day before Lent begins on Ash Wednesday; Mardi Gras) X * given year (>1583) X */ Xdouble Xshrove_tuesday(year) X int year; X{ X return easter_offset(-47.0, year); X} X X/* X * ash_wednesday: X * Christian holidays: compute Julian day for Ash Wednesday X * given year (>1583) X */ Xdouble Xash_wednesday(year) X int year; X{ X return easter_offset(-46.0, year); X} X X/* X * first_sunday_lent: X * Christian holidays: compute Julian day for First Sunday in Lent X * given year (>1583) X */ Xdouble Xfirst_sunday_lent(year) X int year; X{ X return easter_offset(-42.0, year); X} X X/* X * second_sunday_lent: X * Christian holidays: compute Julian day for Second Sunday in Lent X * given year (>1583) X */ Xdouble Xsecond_sunday_lent(year) X int year; X{ X return easter_offset(-35.0, year); X} X X/* X * third_sunday_lent: X * Christian holidays: compute Julian day for Third Sunday in Lent X * given year (>1583) X */ Xdouble Xthird_sunday_lent(year) X int year; X{ X return easter_offset(-28.0, year); X} X X/* X * fourth_sunday_lent: X * Christian holidays: compute Julian day for Fourth Sunday in Lent X * given year (>1583) X */ Xdouble Xfourth_sunday_lent(year) X int year; X{ X return easter_offset(-21.0, year); X} X X/* X * passion_sunday: X * Christian holidays: compute Julian day for Passion Sunday X * (Second Sunday before Easter) X * given year (>1583) X */ Xdouble Xpassion_sunday(year) X int year; X{ X return easter_offset(-14.0, year); X} X X/* X * palm_sunday: X * Christian holidays: compute Julian day for Palm Sunday X * (Sunday before Easter) X * given year (>1583) X */ Xdouble Xpalm_sunday(year) X int year; X{ X return easter_offset(-7.0, year); X} X X/* X * maundy_thursday: X * Christian holidays: compute Julian day for Maundy Thursday X * (Three days prior to Easter) X * given year (>1583) X */ Xdouble Xmaundy_thursday(year) X int year; X{ X return easter_offset(-3.0, year); X} X X/* X * good_friday: X * Christian holidays: compute Julian day for Good Friday X * (Two days prior to Easter) X * given year (>1583) X */ Xdouble Xgood_friday(year) X int year; X{ X return easter_offset(-2.0, year); X} X X/* X * easter_monday: X * Christian holidays: compute Julian day for Easter Monday (Canada) X * given year (>1583) X */ Xdouble Xeaster_monday(year) X int year; X{ X return easter_offset(1.0, year); X} X X/* X * rogation_sunday: X * Christian holidays: compute Julian day for Rogation Sunday X * (Rogation is the period of three days prior to Ascension Day; strictly X * speaking, this is the period Mon-Wed) X * given year (>1583) X */ Xdouble Xrogation_sunday(year) X int year; X{ X return easter_offset(35.0, year); X} X X/* X * ascension_day: X * Christian holidays: compute Julian day for Ascension Day X * (Holy Thursday; fortieth day after Easter, inclusive) X * given year (>1583) X */ Xdouble Xascension_day(year) X int year; X{ X return easter_offset(39.0, year); X} X X/* X * whitsunday: X * Christian holidays: compute Julian day for Whitsunday (Pentecost) X * (Seventh Sunday after Easter) X * given year (>1583) X */ Xdouble Xwhitsunday(year) X int year; X{ X return easter_offset(49.0, year); X} X X/* X * trinity_sunday: X * Christian holidays: compute Julian day for Trinity Sunday X * (Eighth Sunday after Easter) X * given year (>1583) X */ Xdouble Xtrinity_sunday(year) X int year; X{ X return easter_offset(56.0, year); X} X X/* X * corpus_christi: X * Christian holidays: compute Julian day for Corpus Christi X * (First Thursday after Trinity Sunday) X * given year (>1583) X */ Xdouble Xcorpus_christi(year) X int year; X{ X return easter_offset(60.0, year); X} X X/* X * passover: X * Jewish holidays: compute Julian day of Pesach (first day of Passover) X * and establish the Gregorian day of month and month, and Jewish year, X * given Julian year (>1583) X * This formula, due to Karl Friedrich Gauss (1777-1855) is described in X * excruciating detail in the book by Schocken P. 51-61). Note that it X * computes the Julian date, which has to be corrected to a Gregorian date, X * and that it exhibits the eccentricity of always computing the day X * relative to March, so that April 2 appears as March 33, which is also X * corrected below. X * This formula is probably only accurate for years up to and including X * 2000 (tested); I know that it fails for 2011. X */ Xdouble Xpassover(year, jyear) X int *jyear, year; X{ X double etmp, p_day; X int atmp, btmp, ctmp, day_of_week, dtmp, ftmp, gtmp; X int p_month; X X atmp = year + 3760; X *jyear = atmp; X btmp = (12 * atmp + 17) % 19; X ctmp = atmp % 4; X etmp = (1.55424180 * btmp) - (0.003177794 * atmp) X + (ctmp / 4) + 32.04409316; X dtmp = etmp; X etmp = etmp - dtmp; X /* day_of_week is not to be confused with the X value returned by the day_of_week routine; here, Sunday = 1 */ X day_of_week = ((3 * atmp) + (5 * ctmp) + dtmp + 5) % 7; X if (day_of_week == 0 && btmp > 11 && etmp >= 0.89772377) X p_day = dtmp + 1.0; X else if (day_of_week == 1 && btmp > 6 && etmp >= 0.63287037) X p_day = dtmp + 2.0; X else if (day_of_week == 2 || day_of_week == 4 || day_of_week ==6) X p_day = dtmp + 1.0; X else { X p_day = dtmp; X } X ftmp = year / 100; /* Correct to Gregorian date */ X gtmp = ((3 * ftmp) - 5) / 4; X p_day += gtmp; X if (p_day > 31) { /* Correct for March days > 31 */ X p_day -= 31; X p_month = 4; X } X else X p_month = 3; X return julian_day(p_day, p_month, year); X} X X/* X * passover_offset: X * Jewish holidays: compute Julian day as offset from Passover X * given year (>1583) X */ Xdouble Xpassover_offset(offset, year, jyear) X double offset; X int *jyear, year; X{ X double passover(); X X return passover(year, jyear) + offset; X} X X/* X * purim: X * Jewish holidays: compute Julian day and Jewish year for Purim (Feast of Lots) X * given year (>1583) X */ Xdouble Xpurim(year, jyear) X int *jyear, year; X{ X return passover_offset(-30.0, year, jyear); X} X X/* X * shavuot: X * Jewish holidays: compute Julian day and Jewish year for First day of Shavuot X * given year (>1583) X */ Xdouble Xshavuot(year, jyear) X int *jyear, year; X{ X return passover_offset(50.0, year, jyear); X} X X/* X * rosh_hashanah: X * Jewish holidays: compute Julian day and Jewish year for first day of X * Rosh Hashanah (New Year) given year (>1583) X */ Xdouble Xrosh_hashanah(year, jyear) X int *jyear, year; X{ X double atmp; X atmp = passover_offset(163.0, year, jyear); X (*jyear)++; X return atmp; X} X X/* X * yom_kippur: X * Jewish holidays: compute Julian day and Jewish year for Yom Kippur X * given year (>1583) X */ Xdouble Xyom_kippur(year, jyear) X int *jyear, year; X{ X double atmp; X atmp = passover_offset(172.0, year, jyear); X (*jyear)++; X return atmp; X} X X/* X * sukkot: X * Jewish holidays: compute Julian day and Jewish year for X * First day of Sukkot (9 days) given year (>1583) X */ Xdouble Xsukkot(year, jyear) X int *jyear, year; X{ X double atmp; X atmp = passover_offset(177.0, year, jyear); X (*jyear)++; X return atmp; X} X X/* X * simchat_torah: X * Jewish holidays: compute Julian day and Jewish year for Simchat Torah X * (in Diapsora) given year (>1583) X */ Xdouble Xsimchat_torah(year, jyear) X int *jyear, year; X{ X double atmp; X atmp = passover_offset(185.0, year, jyear); X (*jyear)++; X return atmp; X} X X/* X * chanukah: X * Jewish holidays: compute Julian day and Jewish year for X * first day of Chanukah (8 days) given year (>1583) X */ Xdouble Xchanukah(year, jyear) X int *jyear, year; X{ X double atmp; X int btmp, dummy; X X atmp = passover(year, jyear); X btmp = passover((year + 1), &dummy) - atmp; X (*jyear)++; X if (btmp == 355 || btmp == 385) X return atmp + 247.0; X else X return atmp + 246.0; X} X X/* X * islamic_date: X * Islamic holidays: compute Gregorian date(s) and Islamic year for any X * Islamic day, given ISLAMIC day (1-30), ISLAMIC month(1-12), X * and GREGORIAN year (>1583) X * This is complicated by the fact that a given Islamic date can appear as X * often as twice within the same Gregorian year. X */ Xislamic_date( X mday, mmonth, number_of_days, day1, month1, day2, month2, year, myear1, X myear2) X double *day1, *day2, mday; X int mmonth, *month1, *month2, *myear1, *myear2, X *number_of_days, year; X{ X double day; X int count, month, nyear; X double islamic_to_julian(); X X *myear1 = year - 621; /* approx. >= Muslim year */ X nyear = year - 1; X for (count = 0; nyear != year && count <= 100; count++) { X gregorian_date(&day, &month, &nyear, X islamic_to_julian(mday, mmonth, *myear1)); X *myear1 = *myear1 + (year - nyear); X } X if (nyear == year) { X *day1 = day; X *month1 = month; X /* X * See if there is a second occurrence in same Gregorian year X */ X gregorian_date(&day, &month, &nyear, X islamic_to_julian(mday, mmonth, (*myear1 + 1))); X if (nyear == year) { X *day2 = day; X *month2 = month; X *number_of_days = 2; X *myear2 = *myear1 + 1; X } X else { X *number_of_days = 1; X gregorian_date(&day, &month, &nyear, X islamic_to_julian(mday, mmonth, (*myear1 - 1))); X if (nyear == year) { X *day2 = day; X *month2 = month; X *number_of_days = 2; X *myear2 = *myear1 + 1; X } X } X } X/* else return -1; */ X return 0; X} X X/* X * islamic_to_julian: X * Islamic holidays: compute Julian day for any Islamic day, X * given ISLAMIC day (1-30), ISLAMIC month(1-12), and ISLAMIC year (>962) X * Formula from Schocken (p. 66) X */ Xdouble Xislamic_to_julian(mday, mmonth, myear) X double mday; X int mmonth, myear; X{ X double etmp, ftmp, jday; X int atmp, btmp, ctmp, dtmp, nyear; X double corrected_julian_day(); X X nyear = myear + 621; /* approx. Julian year */ X atmp = ((19 * myear) - 4) % 30; X btmp = nyear % 4; X ctmp = (mmonth - 1) / 2; X dtmp = (mmonth - 1) % 2; X etmp = mday + (59.0 * ctmp) + (30.0 * dtmp) + (atmp / 30.0) X + (btmp / 4.0) - (10.8833333 * myear) + 146.8833333; X if (etmp < 0.0) { X ftmp = (4.0 * fabs(etmp)) / 1461.0; X atmp = ftmp; X dtmp = (4.0 * fabs(etmp)); X dtmp = dtmp % 1461; X nyear -= (atmp + 1); X ctmp = nyear % 4; X jday = julian_day(1.0, 3, nyear) X + (((1461.0 - dtmp) + ctmp - btmp) / 4.0) X - 1.0; X return corrected_julian_day(jday); X } X jday = julian_day(1.0, 3, nyear) + etmp - 1.0; X return corrected_julian_day(jday); X} X X/* X * islamic_new_year: X * Islamic holidays: compute Julian date(s) and Islamic year(s) X * for Islamic New Year given JULIAN year (>1583) X * (note: due to the length of the Islamic year (355 d), there can be portions X * of as many as two Islamic New Years within a given Gregorian year; for X * example, according to the algorithm below, the Islamic New Year occured X * twice in 1975: Wednesday 1 January, Sunday 21 December) X * X * Algorithm: Schocken, page 66, which agrees with dates I have obtained for X * the (Gregorian) years 1962-2000. Schocken outlines a Muslim calendar X * consisting of 12 months which are alternately 30 and 29 days in length X * (the first month, Muharram, is 30 days in length). In a 30-year cycle, X * there are 11 leap years in which a 30th day is added to the final month X * of the year. See full details below. X * X * According to Dr. Omar Afzal of Cornell University ((607)255-5118, X * 277-6707; Chairman of the Committee for Crescent Observation; X * irfan@mvax.ee.cornell.edu), this is an antiquated system which has been X * in use for some 400 years, but today the Muslim calendar follows a more X * strictly lunar basis. I wish to acknowledge the Pakistani Consular X * Office of San Francisco (415)788-0677, who referred me to Dr. Muzammil X * Siddiqui of the Orange County Islamic Center, (714)531-1722, who in turn X * referred me to to Dr. Afzal. I thank Dr. Afzal for his patient and lucid X * explanations of the Islamic calendar, and for providing printed matter and X * tables of dates to assist me. Among the sources he provided: X * X * %A U. V. Tsybulsky X * %B Calendar of Middle Eastern Countries X * %I Nauka Publishing House X * %C Moscow X * %L English X * %D 1979 X * X * which provides a scholarly discussion of calendrical conventions in various X * Muslim countries, as well as simple formulas for conversion between X * Gregorian and Islamic dates. It also includes translations of tables which X * originally appeared in: X * X * %A F. R. Unat X * %B Hicri Tarihleri X * %I Turktarih Kurumu Basimevi X * %C Ankara X * %L Turkish X * %D 1959 X * X * Additional tabular material is available in: X * X * %A G. S. P. Freeman-Grenville X * %B The Muslim and Christian Calendars X * %I Oxford University Press X * %C London X * %D 1963 X * X * The Islamic calendar is also known as the Hijri calendar, and dates often X * have "A.H." or "a.h." appended to them to indicate "Anno Hijri." A X * listing of the months and their lengths (in the old scheme): X * X * Month Name Days Days to add to 1 Muharram to get 1st of month X * 1 Muharram 30 0 X * 2 Safar 29 30 X * 3 Rabi' al-Awwal 30 59 X * 4 Rabi' ath-Thani 29 89 X * 5 Jumada al-Ula 30 118 X * 6 Jumada al-Akhir 29 148 X * 7 Rajab 30 177 X * 8 Sha'ban 29 207 X * 9 Ramadan 30 236 X * 10 Shawwal 29 266 X * 11 Dhul-Qa'da 30 295 X * 12 Dhul-Hijja 29 (30) 325 X * X * In the old scheme, used here for simplicity, adherence to this set of rules X * led to a gradual lag of the month behind the actual crescent moon. Thus, X * a leap day was appended to the final month in each of 11 years out of every X * 30 year cycle: (2, 5, 7, 10, 13, 16, 18, 21, 24, 26, 29). If the Hijra year X * is divided by 30, and the remainder is equal to one of these numbers, it is X * a leap year. X * X * The Islamic day begins after sunset, and the beginning of the month is tied X * to the first VISIBLE appearance of the crescent moon, which often lags behind X * the astronomical new moon. Also, the crescent was sometimes computed X * according to Mecca time. There are numerous methods for defining the date X * of the crescent moon (and hence calendar dates) among the various Muslim X * regions of the world. Given these uncertainties, the dates computed here are X * likely to be accurate to only +/- 2 days. X * X * Any errors in this code are my own fault, and X * not intended to offend any members of the Islamic faith. X */ Xislamic_new_year(year, number_of_dates, date1, date2, myear1, myear2) X double *date1, *date2; X int *number_of_dates, *myear1, *myear2, year; X{ X double day1, day2; X int month1, month2; X X if (islamic_date(1.0, 1, number_of_dates, &day1, &month1, &day2, X &month2, year, myear1, myear2) < 0) return -1; X *date1 = julian_day(day1, month1, year); X if (*number_of_dates == 2) *date2 = julian_day(day2, month2, year); X return 0; X} X X/* X * islamic_offset: X * Islamic holidays: compute Julian day(s) for an Islamic date as an offset X * from the Islamic New Year, given (Gregorian) year X */ Xislamic_offset(offset, year, number_of_dates, date1, date2, myear1, myear2) X double *date1, *date2, offset; X int *number_of_dates, *myear1, *myear2, year; X{ X double day, tdate1, tdate2; X int month, tyear1, tyear2; X X (void) islamic_new_year(year, number_of_dates, date1, date2, X myear1, myear2); X if (*number_of_dates == 2) { X tdate2 = *date2 + offset; X gregorian_date(&day, &month, &tyear2, tdate2); X if (tyear2 > year) { X tdate2 = *date1 + offset; X (void) islamic_new_year((year - 1), number_of_dates, X date1, date2, myear1, myear2); X tdate1 = *date1 + offset; X gregorian_date(&day, &month, &tyear1, tdate1); X if (tyear1 == year) { X *date1 = tdate1; X *date2 = tdate2; X *number_of_dates = 2; X *myear2 = *myear1 + 1; X } X else { X *date1 = tdate2; X *number_of_dates = 1; X *myear1 = *myear1 + 1; X } X } X else { X *date1 += offset; X *date2 = tdate2; X } X } X else { X tdate2 = *date1 + offset; X gregorian_date(&day, &month, &tyear2, tdate2); X if (tyear2 > year) { X (void) islamic_new_year((year - 1), number_of_dates, X date1, date2, myear1, myear2); X if (*number_of_dates == 2) { X *date1 = *date2 + offset; X *number_of_dates = 1; X *myear1 = *myear2; X } X else { X *date1 = *date1 + offset; X } X } X else { X (void) islamic_new_year((year - 1), number_of_dates, X date1, date2, myear1, myear2); X if (*number_of_dates == 2) { X tdate1 = *date2 + offset; X *myear1 = *myear2; X } X else { X tdate1 = *date1 + offset; X } X gregorian_date(&day, &month, &tyear1, tdate1); X if (tyear1 == year) { X *date1 = tdate1; X *date2 = tdate2; X *number_of_dates = 2; X *myear2 = *myear1 + 1; X } X else { X *date1 = tdate2; X *myear1 = *myear1 + 1; X *number_of_dates = 1; X } X } X } X} X X/* X * muharram_9: X * Islamic holidays: compute Julian day(s) and Islamic year(s) for X * Muharram 9 (Day of fasting) given year (>1583) X */ Xmuharram_9(year, number_of_dates, date1, date2, myear1, myear2) X double *date1, *date2; X int *number_of_dates, *myear1, *myear2, year; X{ X islamic_offset( X 8.0, year, number_of_dates, date1, date2, myear1, myear2); X} X X/* X * muharram_10: X * Islamic holidays: compute Julian day(s) and Islamic year(s) for X * Muharram 10 (Day of deliverance of Moses from the Pharoah; for Shia Islam, X * martyrdom of Husain) given year (>1583) X */ Xmuharram_10(year, number_of_dates, date1, date2, myear1, myear2) X double *date1, *date2; X int *number_of_dates, *myear1, *myear2, year; X{ X islamic_offset( X 9.0, year, number_of_dates, date1, date2, myear1, myear2); X} X X/* X * muharram_16: X * Islamic holidays: compute Julian day(s) and Islamic year(s) for X * Muharram 16 (Imamat Day; Ismaili Khoja) given year (>1583) X */ Xmuharram_16(year, number_of_dates, date1, date2, myear1, myear2) X double *date1, *date2; X int *number_of_dates, *myear1, *myear2, year; X{ X islamic_offset( X 15.0, year, number_of_dates, date1, date2, myear1, myear2); X} X X/* X * eid_i_milad_un_nabi: X * Islamic holidays: compute Julian day(s) and Islamic year(s) for X * Rabi I 12 (Eid-i-Milad-un-Nabi: The Prophet's Birthday) given year (>1583) X */ Xeid_i_milad_un_nabi(year, number_of_dates, date1, date2, myear1, myear2) X double *date1, *date2; X int *number_of_dates, *myear1, *myear2, year; X{ X islamic_offset( X 70.0, year, number_of_dates, date1, date2, myear1, myear2); X} X X/* X * jumada_al_akhir_23: X * Islamic holidays: compute Julian day(s) and Islamic year(s) for X * Jumada al-Akhir 23 (Birth of Agha Khan IV, Ismaili) given year (>1583) X */ Xjumada_al_akhir_23(year, number_of_dates, date1, date2, myear1, myear2) X double *date1, *date2; X int *number_of_dates, *myear1, *myear2, year; X{ X islamic_offset( X 170.0, year, number_of_dates, date1, date2, myear1, myear2); X} X X/* X * shab_e_miraj: X * Islamic holidays: compute Julian day(s) and Islamic year(s) for X * Rajab 27 (Shab-e-Mi'raj: The Prophet's Ascension) given year (>1583) X */ Xshab_e_miraj(year, number_of_dates, date1, date2, myear1, myear2) X double *date1, *date2; X int *number_of_dates, *myear1, *myear2, year; X{ X islamic_offset( X 203.0, year, number_of_dates, date1, date2, myear1, myear2); X} X X/* X * shab_e_barat: X * Islamic holidays: compute Julian day(s) and Islamic year(s) for X * Shaban 15 (Shab-e-Bara't: Night, followed by day of fasting) given year (>1583) X */ Xshab_e_barat(year, number_of_dates, date1, date2, myear1, myear2) X double *date1, *date2; X int *number_of_dates, *myear1, *myear2, year; X{ X islamic_offset( X 221.0, year, number_of_dates, date1, date2, myear1, myear2); X} X X/* X * ramadan: X * Islamic holidays: compute Julian day(s) and Islamic year(s) for X * Ramadan 1 (Fasting month begins) given year (>1583) X */ Xramadan(year, number_of_dates, date1, date2, myear1, myear2) X double *date1, *date2; X int *number_of_dates, *myear1, *myear2, year; X{ X islamic_offset( X 236.0, year, number_of_dates, date1, date2, myear1, myear2); X} X X/* X * shab_e_qadr: X * Islamic holidays: compute Julian day(s) and Islamic year(s) for X * Ramadan 27 (Shab-e Qadr: Night vigil) given year (>1583) X */ Xshab_e_qadr(year, number_of_dates, date1, date2, myear1, myear2) X double *date1, *date2; X int *number_of_dates, *myear1, *myear2, year; X{ X islamic_offset( X 262.0, year, number_of_dates, date1, date2, myear1, myear2); X} X X/* X * eid_al_fitr: X * Islamic holidays: compute Julian day(s) and Islamic year(s) for X * Shawwal 1 (Eid-al-Fitr: Day of Feast) given year (>1583) X */ Xeid_al_fitr(year, number_of_dates, date1, date2, myear1, myear2) X double *date1, *date2; X int *number_of_dates, *myear1, *myear2, year; X{ X islamic_offset( X 266.0, year, number_of_dates, date1, date2, myear1, myear2); X} X X/* X * dhul_hijja_9: X * Islamic holidays: compute Julian day(s) and Islamic year(s) for X * Dhul-Hijj 9 (Day of Pilgrimage at Arafat, Mecca) given year (>1583) X */ Xdhul_hijja_9(year, number_of_dates, date1, date2, myear1, myear2) X double *date1, *date2; X int *number_of_dates, *myear1, *myear2, year; X{ X islamic_offset( X 333.0, year, number_of_dates, date1, date2, myear1, myear2); X} X X/* X * eid_al_adha: X * Islamic holidays: compute Julian day(s) and Islamic year(s) for X * Dhul-Hijj 10 (Eid-al-Adha: Day of Abraham's Sacrifice) given year (>1583) X */ Xeid_al_adha(year, number_of_dates, date1, date2, myear1, myear2) X double *date1, *date2; X int *number_of_dates, *myear1, *myear2, year; X{ X islamic_offset( X 334.0, year, number_of_dates, date1, date2, myear1, myear2); X} X X/* X * ghadir: X * Islamic holidays: compute Julian day(s) and Islamic year(s) for X * Dhul-Hijj 18 (Ghadir: Ali's Nomination) given year (>1583) X */ Xghadir(year, number_of_dates, date1, date2, myear1, myear2) X double *date1, *date2; X int *number_of_dates, *myear1, *myear2, year; X{ X islamic_offset( X 342.0, year, number_of_dates, date1, date2, myear1, myear2); X} X X/* X * print_islamic_string: X * Print formatted date string(s) of form: X * Monday 1 August 1988 (Islamic year 1409) X * given string labelling date, (Gregorian) year of event, and function which X * takes (Gregorian) year as an argument and produces: the (integer) number of X * Gregorian dates (1 or 2), the first and second (Julian) days, and the first X * and second Islamic years. X */ Xprint_islamic_string(string, year, func) X char *string; X int year; X int (*func) (); X{ X X char *date; X double date1, date2, day, holiday; X int month, myear1, myear2, number_of_dates; X char *date_string(); X X holiday = (*func) ( X year, &number_of_dates, &date1, &date2, &myear1, &myear2); X if (holiday < 0) X (void) printf("Can not determine requested date\n"); X else { X (void) printf("%s (%d) Julian day: %f\n", string, year, date1); X gregorian_date(&day, &month, &year, date1); X date = date_string(get_day_of_week(day, month, year), X day, month, year); X (void) printf("%s (%d): %s", string, year, date); X (void) printf(" (Islamic year %d)\n", myear1); X if (number_of_dates == 2) { X (void) printf( X "%s (%d) Julian day: %f\n", string, year, X date2); X gregorian_date(&day, &month, &year, date2); X date = date_string(get_day_of_week(day, month, year), X day, month, year); X (void) printf("%s (%d): %s", string, year, date); X (void) printf(" (Islamic year %d)\n", X myear2); X } X } X} X X/* X * print_date_and_time_string: X * Print formatted date/time string of form: 10:42 Thursday 8 December 1988 X * given string labelling date, year of event, and function which takes year X * as an argument and produces Julian day, X */ Xprint_date_and_time_string(string, year, func) X char *string; X int year; X double (*func)(); X{ X char *date; X double btmp, ctmp, day, holiday; X int atmp, hour, min, month; X char *date_time_string(); X X holiday = (*func) (year); X (void) printf("%s (%d) Julian day: %f\n", string, year, holiday); X gregorian_date(&day, &month, &year, holiday); X atmp = day; X btmp = day - atmp; X hour = btmp * 24.0; X ctmp = (btmp - (hour / 24.0)) * 1440.0; X min = ctmp; X date = date_time_string(hour, min, get_day_of_week(day, month, year), X day, month, year); X (void) printf("%s (%d): %s\n", string, year, date); X} X X/* X * print_date_string: X * Print formatted date string of form: Thursday 8 December 1988 X * given string labelling date, year of event, and function which takes year X * as an argument and produces Julian day. X */ Xprint_date_string(string, year, func) X char *string; X int year; X double (*func) (); X{ X char *date; X double day, holiday; X int month; X char *date_string(); X X holiday = (*func) (year); X (void) printf("%s (%d) Julian day: %f\n", string, year, holiday); X gregorian_date(&day, &month, &year, holiday); X date = date_string(get_day_of_week(day, month, year), day, month, year); X (void) printf("%s (%d): %s\n", string, year, date); X} X X/* X * print_jewish_string: X * Print formatted date string of form: Thursday 8 December 1988 (NYEAR) X * given string labelling date, year of event, and function which takes year X * as an argument, sets the value of a non-Gregorian year (NYEAR), and produces X * the Julian day. X */ Xprint_jewish_string(string, year, func) X char *string; X int year; X double (*func) (); X{ X char *date; X double day, holiday; X int month, nyear; X char *date_string(); X X holiday = (*func) (year, &nyear); X (void) printf("%s (%d) Julian day: %f\n", string, year, holiday); X gregorian_date(&day, &month, &year, holiday); X date = date_string_2(get_day_of_week(day, month, year), day, month, X year, nyear); X (void) printf("%s (%d): %s\n", string, year, date); X} X X/* X * extract time of day from Julian day X */ Xchar * Xjulian_time(jday) Xdouble jday; X{ X double h1, floor(); X int hours, minutes; X X h1 = (jday - floor(jday)) * 24.; /* number of hours & frac of hours */ X hours = (int) floor(h1); X minutes = (int) ((h1 - (double) hours) * 60.); X sprintf(timebuf, " at %d:%02d", hours, minutes); X return(timebuf); X} X X/* X * End of code X */ X#endif /* NO_HOLIDAYS */ SHAR_EOF if test 44349 -ne "`wc -c < 'datelib.c'`" then echo shar: error transmitting "'datelib.c'" '(should have been 44349 characters)' fi fi # end of overwriting check echo shar: extracting "'day.cursor'" '(283 characters)' if test -f 'day.cursor' then echo shar: will not over-write existing file "'day.cursor'" else sed 's/^ X//' << \SHAR_EOF > 'day.cursor' X/* $Header: day.cursor,v 2.1 89/05/09 14:31:03 billr Exp $ */ X/* Format_version=1, Width=16, Height=16, Depth=1, Valid_bits_per_item=16 X */ X 0x0000, 0x0000, 0x0000, 0x01F0, 0x0700, 0x1DFF, 0x7000, 0xC000, X 0x7000, 0x1DFF, 0x0700, 0x01F0, 0x0000, 0x0000, 0x0000, 0x0000 SHAR_EOF if test 283 -ne "`wc -c < 'day.cursor'`" then echo shar: error transmitting "'day.cursor'" '(should have been 283 characters)' fi fi # end of overwriting check echo shar: extracting "'event.c'" '(6577 characters)' if test -f 'event.c' then echo shar: will not over-write existing file "'event.c'" else sed 's/^ X//' << \SHAR_EOF > 'event.c' X/* X * $Header: event.c,v 2.1 89/05/09 14:23:23 billr Exp $ X */ X/* X * event.c X * X * Author: Philip Heller, Sun Microsystems. Inc. X * X * Original source Copyright (C) 1987, Sun Microsystems, Inc. X * All Rights Reserved X * Permission is hereby granted to use and modify this program in source X * or binary form as long as it is not sold for profit and this copyright X * notice remains intact. X * X * X * Changes/additions by: Bill Randle, Tektronix, Inc. X * X * Changes and additions Copyright (C) 1988, 1989 Tektronix, Inc. X * All Rights Reserved X * Permission is hereby granted to use and modify the modifications in source X * or binary form as long as they are not sold for profit and this copyright X * notice remains intact. X */ X/******************************************************** X * * X * Main driver and month and year event routines * X * for main subwindow * X * * X ********************************************************/ X X X#include X#include X#include X#include X#include "ct.h" X#include "event.h" X Xextern Frame frame; Xextern Frame fframe, sframe, mframe; Xextern struct tm olddate; Xextern int update_interval, show_time; Xextern char timestr[], todays_date[]; Xextern Icon icon; XNotify_value myframe_interposer(); X Xvoid Xmainsw_inputevent(canvas, event) XCanvas canvas; XEvent *event; X{ X /* check for L7 key and close frame if found */ X if (event_id(event) == KEY_LEFT(7) && event_is_up(event)) X close_frame(); X else X switch (mainsw_state) { X case DISPLAYING_DAY: X day_inputevent(canvas, event); X break; X case DISPLAYING_WEEK: X week_inputevent(canvas, event); X break; X case DISPLAYING_MONTH: X month_inputevent(canvas, event); X break; X case DISPLAYING_YEAR: X year_inputevent(canvas, event); X break; X } X} X Xmonth_inputevent(canvas, event) XCanvas canvas; XEvent *event; X{ X int i, x, y, week_index, new_day; X X /* translate coordinates to pixwin space */ X event = canvas_window_event(canvas, event); X x = event_x(event); X y = event_y(event); X if (event_id(event) != MS_LEFT) X return; X X if (event_is_up(event)) { /* Button up. */ X fix_current_day(); X if (selected_type == DAY) { X mainsw_state = DISPLAYING_DAY; X window_set(canvas, WIN_CURSOR, day_cursor, 0); X draw_day(); X } X else if (selected_type == WEEK) { X mainsw_state = DISPLAYING_WEEK; X window_set(canvas, WIN_CURSOR, week_cursor, 0); X draw_week(); X } X return; X } X X /* Button down. */ X selected_type = NONE; X for (i=0; i= boxlims[i].lowx) && X (x <= boxlims[i].highx) && X (y >= boxlims[i].lowy) && X (y <= boxlims[i].highy)) { X current.tm_mday = i + 1; X selected_type = DAY; X pw_write(main_pixwin,boxlims[i].lowx+3, X boxlims[i].lowy+3,58,58,PIX_NOT(PIX_DST),NULL,0,0); X return; X } X } X for (i=0; i<6; i++) { /* No. In a week? */ X if (week_arrows[i].active == 0) X return; X if ((x >= week_arrows[i].left) && X (x <= week_arrows[i].right) && X (y >= week_arrows[i].top) && X (y <= week_arrows[i].bottom)) { X week_index = i; X current.tm_mday = -current.tm_wday + 1 + (7 * week_index); X selected_type = WEEK; X pw_write(main_pixwin,week_arrows[week_index].left, X week_arrows[week_index].top,smallarrow_pr->pr_size.x, X smallarrow_pr->pr_size.y,PIX_SRC^PIX_DST, X smallarrow_pr,0,0); X return; X } X } X} X Xyear_inputevent(canvas, event) XCanvas canvas; XEvent *event; X{ X int x, y, i; X static int mday; X X /* translate coordinates to pixwin space */ X event = canvas_window_event(canvas, event); X x = event_x(event); X y = event_y(event); X if (event_id(event) != MS_LEFT) X return; X if (event_is_up(event)) { /* Button up. */ X if (selected_type == MONTH) { X mainsw_state = DISPLAYING_MONTH; X window_set(canvas, WIN_CURSOR, month_cursor, 0); X draw_month(); X } X return; X } X X /* Button down. */ X selected_type = NONE; X for (i=0; i<12; i++) { /* In a month? */ X if ((x >= mboxlims[i].lowx) && X (x <= mboxlims[i].highx) && X (y >= mboxlims[i].lowy) && X (y <= mboxlims[i].highy)) { X selected_type = MONTH; X current.tm_mday = 1; X current.tm_mon = i; X pw_write(main_pixwin,mboxlims[i].lowx, X mboxlims[i].lowy,7*ybox_width,ybox_height-1,PIX_NOT(PIX_DST),NULL,0,0); X break; X } X } X} X XNotify_value Xcheck_close(client, event, arg, when) XNotify_client client; XEvent *event; XNotify_arg arg; XNotify_event_type when; X{ X /* check for L7 key and close frame if found */ X /*** DEBUG ***/ X /* X fprintf(stderr, "checking for L7: event = %d\n", event_id(event)); X */ X if (event_id(event) == KEY_LEFT(7) && event_is_up(event)) X return (myframe_interposer(client, event, arg, when)); X else X return (notify_next_event_func(client, event, arg, when)); X} X Xclose_frame() X{ X Icon cur_icon; X X /* save some information as we close */ X if (mainsw_state == DISPLAYING_DAY && day_is_open) X close_day(); X /* if frame not closed yet, close it now (for the canvas) */ X if (!(int)window_get(frame, FRAME_CLOSED)) X window_set(frame, FRAME_CLOSED, TRUE, 0); X olddate = current; X if (fframe) { X /* kill off future appt popup */ X window_destroy(fframe); X fframe = 0; X } X#ifndef NO_SUN_MOON X /* kill sun/moon data frames */ X if (mframe) X mframe_done(0); X if (sframe) X sframe_done(0); X#endif X check_calendar(); /* update icon */ X if (show_time) { X /* update time label */ X strcpy(timestr, todays_date+10); X if (update_interval == 60) X /* display hh:mm */ X timestr[6] = '\0'; X else X /* display hh:mm:ss */ X timestr[9] = '\0'; X cur_icon = (Icon) window_get(frame, FRAME_ICON); X icon_set(cur_icon, ICON_LABEL, timestr, 0); X window_set(frame, FRAME_ICON, cur_icon, 0); X } X} SHAR_EOF if test 6577 -ne "`wc -c < 'event.c'`" then echo shar: error transmitting "'event.c'" '(should have been 6577 characters)' fi fi # end of overwriting check echo shar: extracting "'event.h'" '(1462 characters)' if test -f 'event.h' then echo shar: will not over-write existing file "'event.h'" else sed 's/^ X//' << \SHAR_EOF > 'event.h' X/* X * $Header: event.h,v 2.1 89/05/09 14:25:16 billr Exp $ X */ X/* X * event.h X * X * Author: Philip Heller, Sun Microsystems. Inc. X * X * Original source Copyright (C) 1987, Sun Microsystems, Inc. X * All Rights Reserved X * Permission is hereby granted to use and modify this program in source X * or binary form as long as it is not sold for profit and this copyright X * notice remains intact. X * X * X * Changes/additions by: Bill Randle, Tektronix, Inc. X * X * Changes and additions Copyright (C) 1988, 1989 Tektronix, Inc. X * All Rights Reserved X * Permission is hereby granted to use and modify the modifications in source X * or binary form as long as they are not sold for profit and this copyright X * notice remains intact. X */ X Xextern struct dayslot slots[]; Xextern int mainsw_state, day_is_open; Xextern struct rect_limits boxlims[]; Xextern struct rect_limits mboxlims[]; Xextern int selected_type, read_only, new_entry; Xextern int dayslot_width, nr_weekdays, day_message_size; Xextern int dayslot_height, weekslot_height, weekslot_width; Xextern int ybox_height, ybox_width; Xextern struct weekrect week_boxes[]; Xextern Pixwin *main_pixwin; Xextern Pixfont *font; Xextern Cursor month_cursor, week_cursor, day_cursor; Xextern Pixrect *smallarrow_pr, *arrowhead_pr, *arrowshaft_pr; Xextern struct week_arrow week_arrows[]; Xextern struct tm current; Xextern struct tm today; Xextern Pixrect *timeslot_td_pr, *morebutton; X SHAR_EOF if test 1462 -ne "`wc -c < 'event.h'`" then echo shar: error transmitting "'event.h'" '(should have been 1462 characters)' fi fi # end of overwriting check # End of shell archive exit 0