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) ; }