rokicki@polya.Stanford.EDU (Tomas G. Rokicki) (08/19/88)
/*
* Written by Tomas Rokicki of Radical Eye Software.
*
* Here's an updated ShowDate() routine, as requested by Rob
* Peck. This one even has some limited explanations of how
* it works! It sets the day of week as well as month, day,
* and year from the values returned by DateStamp().
*
* Note that the original code published in Peck's book, would
* fail for dates prior to 1984. When compiled with 16-bit
* integers, it would fail for dates after 2007. The current
* code will work with any size integer from Amiga day 0 until
* March 1, 2100.
*/
int w, m, d, y ;
main(argc, argv)
int argc ;
char *argv[] ;
{
long v[3] ;
DateStamp(v) ;
ShowDate(v) ;
}
static char *months[]={"", "January", "February", "March", "April", "May",
"June", "July", "August", "September", "October", "November",
"December"} ;
static char *days[]={"", "Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"} ;
/*
* This routine sets global variables $m$, $d$, $y$, and $w$
* to the current month, day, year, and day of week. Months,
* days, and day of weeks all start at 1 with first members
* January, the first, and Sunday, respectively.
*/
ShowDate(v)
long *v ;
{
long n ;
/*
* Set $n$ to the number of days since Amiga day -671, which is
* March 1, 1976. It's easier to figure years starting in March,
* since then the lengths of the months are 31, 30, 31, 30, 31,
* 31, 30, 31, 30, 31, 31, 28. This is almost linear.
*/
n = v[0] + 671 ;
/*
* The easiest is the weekday. This is simply the number of days
* modulo 7, corrected for the start date. March 1, 1976 was a
* Monday, so we add 1 to get back to a Sunday, take the modulo,
* and add one to start our days on Sunday.
*/
w = (n + 1) % 7 + 1 ;
/*
* There are exactly 1461 days every four years, until 2100, which
* is the first year divisible by 4 that is not a leap year AA
* (After Amiga.) This gives the years lengths of 365 (1976),
* 365 (1977), 365 (1978), and 366 (1979). Note that this is
* correct because we start our years in March, so 1979 is the
* leap year.
*/
y = (4 * n + 3) / 1461 ;
/*
* We now subtract off the years (see them melt off her face.)
* We use a long constant for 16-bit systems. Again we use the
* fact that the leap year is the fourth year, not the first.
*/
n -= 1461L * y / 4 ;
/*
* Now we can adjust the year to the proper value by adding
* 1976.
*/
y += 1976 ;
/*
* We calculate the month. Since we start in March, the length
* of the months are always 30 or 31, except for the last month,
* which is shorter. This is fortunate, as it allows us to use
* a simple mathematical formula for the month. The lengths of
* the months are (31, 30, 31, 30, 31), repeated three times and
* the end lopped off. So, our slope is 153/5. An intercept of
* 2 gives us the 31 and 30 lengths.
*/
m = (5 * n + 2) / 153 ;
/*
* And now we subtract off the months. Oh, yeah, we add 1 because
* the first day of each month is the first, not the zeroth.
*/
d = n - (153 * m + 2) / 5 + 1 ;
/*
* Now we convert from March-based years back to January-based
* years. We add 2 for this shift, and another 1 to give us
* January = 1 through December = 12.
*/
m += 3 ;
/*
* And, if we've gone over 12, we increment the year.
*/
if (m > 12) {
y++ ;
m -= 12 ;
}
/*
* That's it!
*/
printf("%s, %s %d, %d\n", days[w], months[m], d, y) ;
}