Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!maverick.ksu.ksu.edu!umriscc!ee.umr.edu From: jmd@ee.umr.edu (Jim Dumser) Newsgroups: comp.binaries.ibm.pc.d Subject: Re: (Astronomical) Julian Date Source Wanted Message-ID: <2609@umriscc.isc.umr.edu> Date: 18 Apr 91 13:03:18 GMT References: <9873.2808dac2@ohstpy.mps.ohio-state.edu> <40790007@hpcvra.cv.hp.com.> Sender: news@umriscc.isc.umr.edu Organization: University of Missouri - Rolla Lines: 238 Well, don't know if this is Astronimical or USGov't Julian, but here are some routines that were published in Computer Language (Dec 90). There is also a discussion in the March 91 issue, which I haven't got to yet, that covers these same routines. I also thought there was a fix published sometime inbetween Dec 90 and March 91, but I can't seem to find it right now. Jim #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'date.c' <<'END_OF_FILE' Xstatic char *rcsid = "$Id: date.c,v 1.1 1991/03/22 06:05:45 jmd Exp $"; X X#include "date.h" X X X/* X * Calculate the Julian day number for a specified day, month, and year. X * B.C. years are negative. X */ X XDATE julian_date(int day, int month, int year) X { X int a, b = 0; X float year_corr; X X /* correct for negative year */ X year_corr = (year > 0 ? 0.0 : 0.75); X X if (month <= 2) { X year--; X month += 12; X } X X /* cope with Gregorian calendar reform */ X if (year * 10000.0 + month * 100.0 + day >= 15821015.0) { X a = year / 100; X b = 2 - a + a / 4; X } X X return (DATE)((long)(365.25 * year - year_corr) + X (long)(30.6001 * (month + 1)) + day + 1720994L + b); X } X X X/* X * Calculate the day, month, and year corresponding to a Julian day number. X * B.C. years are negative. X */ X Xvoid calendar_date(DATE jdate, int *day, int *month, int *year) X { X long a, b, c, d, e, z, alpha; X X z = jdate + 1; X X /* cope with Gregorian calendar reform */ X if (z < 2299161L) a = z; X else { X alpha = (long)((z - 1867216.25) / 36524.25); X a = z + 1 + alpha - alpha / 4; X } X X b = a + 1524; X c = (long)((b - 122.1) / 365.25); X d = (long)(365.25 * c); X e = (long)((b - d) / 30.6001); X *day = (int)(b - d - (long)(30.6001 * e)); X *month = (int)(e < 13.5 ? e - 1 : e - 13); X *year = (int)(*month > 2.5 ? c - 4716 : c - 4715); X } X X X/* X * Calculate the day of the week for the specified Julian day number: X * 1 = Sunday, 2 = Monday, ..., 7 = Saturday X */ X Xint day_of_week(DATE date) X { X return (int)((date + 2) % 7 + 1); X } X X X/* X * Validate the specified day, month, and year. For example, the following X * dates are not valid: X * Feb 29, 1973 not a leap year X * Apr 31 April only has 30 days X */ X Xint valid_date(int day, int month, int year) X { X int cday, cmonth, cyear; X X /* convert date to julian day number and back */ X calendar_date(julian_date(day, month, year), &cday, &cmonth, &cyear); X X /* date is valid if day, month, year didn't change */ X return ((day == cday) && (month == cmonth) && (year == cyear)); X } X X X/* X * Calculate the Julian day number of Easter for the specified year, X * which can't be negative. X */ X XDATE easter(int year) X { X int a, b, c, d, e, f, g, h, i, k, l, m, n, p, day, month; X X if (year >= 1583) { X /* Gregorian calendar */ X a = year % 19; b = year / 100; X c = year % 100; d = b / 4; X e = b % 4; f = (b + 8) / 25; X g = (b - f + 1) / 3; h = (19 * a + b - d - g + 15) % 30; X i = c / 4; k = c % 4; X l = (32 + 2 * e + 2 * i - h - k) % 7; X m = (a + 11 * h + 22 * l) / 451; X n = (h + l - 7 * m + 114) / 31; X p = (h + l - 7 * m + 114) % 31; X month = n; day = p + 1; X } else { X /* Julian calendar */ X a = year % 4; b = year % 7; X c = year % 19; d = (19 * c + 15) % 30; X e = (2 * a + 4 * b - d + 34) % 7; X f = (d + e + 114) / 31; X g = (d + e + 114) % 31; X month = f; day = g + 1; X } X X return julian_date(day, month, year); X } X X X/* X * Print a calendar for the specified month. X */ X Xvoid month_calendar(int month, int year) X { X DATE b_date, e_date, c_date, easter_d; X int day, c_day, c_month, c_year; X X /* calculate Julian numbers for first and last days of the month */ X b_date = julian_date(1, month, year); X if (month < 12) e_date = julian_date(1, month + 1, year) - 1; X else e_date = julian_date(1, 1, year + 1) - 1; X X printf("%2d/%d:\n\n", month, year); X printf("Sun Mon Tue Wed Thu Fri Sat\n\n"); X X /* put first day of month under correct day column */ X for (day = 1; day < day_of_week(b_date); day++) printf(" "); X X /* print all the days */ X for (c_date = b_date; c_date <= e_date; c_date++) { X calendar_date(c_date, &c_day, &c_month, &c_year); X printf("%3d ", c_day); X if (day_of_week(c_date) == 7) printf("\n"); X } X X /* if Easter happens this month, print the date */ X easter_d = easter(year); X if (year >= 0 && easter_d >= b_date && easter_d <= e_date) { X calendar_date(easter_d, &c_day, &c_month, &c_year); X printf("\n\nEaster: %2d/%2d", c_month, c_day); X } X X printf("\n\n\n"); X } X X X/* X * Print a one-year calendar for the specified year. X */ X Xvoid year_calendar(int year) X { X int month; X X for (month = 1; month <= 12; month++) month_calendar(month, year); X } END_OF_FILE if test 4477 -ne `wc -c <'date.c'`; then echo shar: \"'date.c'\" unpacked with wrong size! fi # end of 'date.c' fi if test -f 'date.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'date.h'\" else echo shar: Extracting \"'date.h'\" \(462 characters\) sed "s/^X//" >'date.h' <<'END_OF_FILE' X/* X * $Id: date.h,v 1.1 1991/03/22 06:05:45 jmd Exp $ X */ X X X/* Dates are represented as Julian day numbers, stored as long integers */ X Xtypedef long DATE; X X X/* ANSI prototypes */ X XDATE julian_date(int day, int month, int year); Xvoid calendar_date(DATE jdate, int *day, int *month, int *year); Xint valid_date(int day, int month, int year); Xint day_of_week(DATE date); XDATE easter(int year); Xvoid month_calendar(int month, int year); Xvoid year_calendar(int year); END_OF_FILE if test 462 -ne `wc -c <'date.h'`; then echo shar: \"'date.h'\" unpacked with wrong size! fi # end of 'date.h' fi echo shar: End of shell archive. exit 0