home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!utcsri!skule.ecf!torn!nott!cunews!revcan!software.mitel.com!kim!kim
- From: kim@Software.Mitel.COM (Kim Letkeman)
- Newsgroups: comp.lang.pascal
- Subject: Re: Day of week on a given date
- Message-ID: <KIM.92Nov17115401@kim.Software.Mitel.COM>
- Date: 17 Nov 92 16:54:01 GMT
- References: <1992Nov17.042319.29002@cs.unca.edu>
- Sender: kim@Software.Mitel.COM
- Organization: MITEL Public Switching, Kanata, Ontario, Canada
- Lines: 152
- In-reply-to: snodgras@cs.unca.edu's message of 17 Nov 92 04:23:19 GMT
-
- In article <1992Nov17.042319.29002@cs.unca.edu> snodgras@cs.unca.edu (Ryan Snodgrass) writes:
-
- | Does anyone know how to get the day of week given a specified date,
- | for example if the function were passed the date "11-16-92" then it would
- | return some number representing Monday? (I assume 1)
- |
- | If you could give me an example, or of where to look to get an example I
- | would really appreciate it.
-
- Here are some snippets of comments and code (C, but easy to
- translate). It handles year 1 through year 9999 and has been fully
- verified against all of cal's possible outputs.
-
- ---------------------------
-
- I take 1 jan 1 to be a Saturday because that's what cal says and I
- couldn't change that even if I was dumb enough to try. From this we
- can easily calculate the day of week for any date. The algorithm for a
- zero based day of week:
-
- calculate the number of days in all prior years (year-1)*365
- add the number of leap years (days?) since year 1
- (not including this year as that is covered later)
- add the day number within the year
- this compensates for the non-inclusive leap year
- calculation
- if the day in question occurs before the gregorian reformation
- (3 sep 1752 for our purposes), then simply return
- (value so far - 1 + SATURDAY's value of 6) modulo 7.
- if the day in question occurs during the reformation (3 sep 1752
- to 13 sep 1752 inclusive) return THURSDAY. This is my
- idea of what happened then. It does not matter much as
- this program never tries to find day of week for any day
- that is not the first of a month.
- otherwise, after the reformation, use the same formula as the
- days before with the additional step of subtracting the
- number of days (11) that were adjusted out of the calendar
- just before taking the modulo.
-
- It must be noted that the number of leap years calculation is
- sensitive to the date for which the leap year is being calculated. A
- year that occurs before the reformation is determined to be a leap
- year if its modulo of 4 equals zero. But after the reformation, a year
- is only a leap year if its modulo of 4 equals zero and its modulo of
- 100 does not. Of course, there is an exception for these century
- years. If the modulo of 400 equals zero, then the year is a leap year
- anyway. This is, in fact, what the gregorian reformation was all about
- (a bit of error in the old algorithm that caused the calendar to be
- inaccurate.)
-
- #define JANUARY 1
- #define THURSDAY 4 /* for reformation */
- #define SATURDAY 6 /* 1 Jan 1 was a saturday */
- #define FIRST_MISSING_DAY 639787 /* 3 Sep 1752 */
- #define NUMBER_MISSING_DAYS 11 /* 11 day correction */
-
- static int days_in_month[2][13] =
- {{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
- {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
-
- [...]
-
- /****************************************************************************
- * leap_year accounts for the gregorian reformation in 1752. *
- ****************************************************************************/
-
- int leap_year (year)
- int year;
- {
- if (year<=1752) return (year%4 == 0);
- else return (year%4 == 0 && year%100 != 0 || year%400 == 0);
- }
-
- /****************************************************************************
- * day_in_year unabashedly borrowed from K&R, where it was called *
- * day_of_year ... returns the 1 based day number within the year. *
- ****************************************************************************/
-
- int day_in_year (day, month, year)
- int day;
- int month;
- int year;
- {
- int i;
- int leap;
-
- leap = leap_year (year);
- for (i = 1; i < month; i++) day += days_in_month [leap] [i];
- return (day);
- }
-
- /****************************************************************************
- * centuries_since_1700 returns the number of xx00 years that have occured *
- * since 1700 *not inclusive*. *
- ****************************************************************************/
-
- int centuries_since_1700 (year)
- int year;
- {
- if (year > 1700) return ((year/100)-17);
- else return (0);
- }
-
- /****************************************************************************
- * quad_centuries_since_1700 returns the number of xx00 years whose modulo *
- * of 400 == 0, also since 1700. *
- ****************************************************************************/
-
- int quad_centuries_since_1700 (year)
- int year;
- {
- if (year > 1600) return ((year-1600)/400);
- else return (0);
- }
-
- /****************************************************************************
- * leap_years_since_year_1 returns the number of leap years between year 1 *
- * and this year *not inclusive*. *
- ****************************************************************************/
-
- int leap_years_since_year_1 (year)
- int year;
- {
- --year;
- return (year/4 - centuries_since_1700 (year)
- + quad_centuries_since_1700 (year));
- }
-
- /****************************************************************************
- * day_in_week returns a zero based day number for any date from 1 jan 1 *
- * to 31 dec 9999. Assumes the gregorian reformation eliminates 3 sep 1752 *
- * through 13 sep 1752. Returns THURSDAY (4) for all missing days. *
- ****************************************************************************/
-
- int day_in_week (day, month, year)
- int day;
- int month;
- int year;
- {
- long temp;
-
- temp = (long)(year-1)*365 + leap_years_since_year_1 (year)
- + day_in_year (day, month, year);
- if (temp < FIRST_MISSING_DAY) return ((temp-1+SATURDAY)%7);
- if (temp >= (FIRST_MISSING_DAY + NUMBER_MISSING_DAYS))
- return (((temp-1+SATURDAY) - NUMBER_MISSING_DAYS)%7);
- return (THURSDAY);
- }
-
- Enjoy.
- --
- Kim Letkeman kim@Software.Mitel.COM
-