home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #27 / NN_1992_27.iso / spool / comp / lang / pascal / 6669 < prev    next >
Encoding:
Internet Message Format  |  1992-11-17  |  6.2 KB

  1. Path: sparky!uunet!utcsri!skule.ecf!torn!nott!cunews!revcan!software.mitel.com!kim!kim
  2. From: kim@Software.Mitel.COM (Kim Letkeman)
  3. Newsgroups: comp.lang.pascal
  4. Subject: Re: Day of week on a given date
  5. Message-ID: <KIM.92Nov17115401@kim.Software.Mitel.COM>
  6. Date: 17 Nov 92 16:54:01 GMT
  7. References: <1992Nov17.042319.29002@cs.unca.edu>
  8. Sender: kim@Software.Mitel.COM
  9. Organization: MITEL Public Switching, Kanata, Ontario, Canada
  10. Lines: 152
  11. In-reply-to: snodgras@cs.unca.edu's message of 17 Nov 92 04:23:19 GMT
  12.  
  13. In article <1992Nov17.042319.29002@cs.unca.edu> snodgras@cs.unca.edu (Ryan Snodgrass) writes:
  14.  
  15. | Does anyone know how to get the day of week given a specified date,
  16. | for example if the function were passed the date "11-16-92" then it would
  17. | return some number representing Monday? (I assume 1)
  18. | If you could give me an example, or of where to look to get an example I
  19. | would really appreciate it.
  20.  
  21. Here are some snippets of comments and code (C, but easy to
  22. translate). It handles year 1 through year 9999 and has been fully
  23. verified against all of cal's possible outputs.
  24.  
  25. ---------------------------
  26.  
  27. I take 1 jan 1 to be a Saturday because that's what cal says and I
  28. couldn't change that even if I was dumb enough to try. From this we
  29. can easily calculate the day of week for any date. The algorithm for a
  30. zero based day of week:
  31.  
  32.     calculate the number of days in all prior years (year-1)*365
  33.     add the number of leap years (days?) since year 1 
  34.         (not including this year as that is covered later)
  35.     add the day number within the year
  36.         this compensates for the non-inclusive leap year
  37.         calculation
  38.     if the day in question occurs before the gregorian reformation
  39.         (3 sep 1752 for our purposes), then simply return 
  40.         (value so far - 1 + SATURDAY's value of 6) modulo 7.
  41.     if the day in question occurs during the reformation (3 sep 1752
  42.         to 13 sep 1752 inclusive) return THURSDAY. This is my
  43.         idea of what happened then. It does not matter much as
  44.         this program never tries to find day of week for any day
  45.         that is not the first of a month.
  46.     otherwise, after the reformation, use the same formula as the
  47.         days before with the additional step of subtracting the
  48.         number of days (11) that were adjusted out of the calendar
  49.         just before taking the modulo.
  50.  
  51. It must be noted that the number of leap years calculation is
  52. sensitive to the date for which the leap year is being calculated. A
  53. year that occurs before the reformation is determined to be a leap
  54. year if its modulo of 4 equals zero. But after the reformation, a year
  55. is only a leap year if its modulo of 4 equals zero and its modulo of
  56. 100 does not. Of course, there is an exception for these century
  57. years. If the modulo of 400 equals zero, then the year is a leap year
  58. anyway. This is, in fact, what the gregorian reformation was all about
  59. (a bit of error in the old algorithm that caused the calendar to be
  60. inaccurate.)
  61.  
  62. #define        JANUARY            1
  63. #define        THURSDAY        4    /* for reformation */
  64. #define        SATURDAY         6    /* 1 Jan 1 was a saturday */
  65. #define        FIRST_MISSING_DAY     639787    /* 3 Sep 1752 */
  66. #define        NUMBER_MISSING_DAYS     11    /* 11 day correction */
  67.  
  68. static int    days_in_month[2][13] = 
  69.         {{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
  70.          {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
  71.  
  72. [...]
  73.  
  74. /****************************************************************************
  75.  * leap_year accounts for the gregorian reformation in 1752.                *
  76.  ****************************************************************************/
  77.  
  78. int leap_year (year)
  79. int    year;
  80. {
  81.     if (year<=1752) return (year%4 == 0);
  82.     else        return (year%4 == 0 && year%100 != 0 || year%400 == 0);
  83. }
  84.  
  85. /****************************************************************************
  86.  * day_in_year unabashedly borrowed from K&R, where it was called           *
  87.  * day_of_year ... returns the 1 based day number within the year.          *
  88.  ****************************************************************************/
  89.  
  90. int day_in_year (day, month, year)
  91. int    day;
  92. int    month;
  93. int    year;
  94. {
  95.     int    i;
  96.     int    leap;
  97.  
  98.     leap = leap_year (year);
  99.     for (i = 1; i < month; i++) day += days_in_month [leap] [i];
  100.     return (day);
  101. }
  102.  
  103. /****************************************************************************
  104.  * centuries_since_1700 returns the number of xx00 years that have occured  *
  105.  * since 1700 *not inclusive*.                                              *
  106.  ****************************************************************************/
  107.  
  108. int centuries_since_1700 (year)
  109. int    year;
  110. {
  111.     if (year > 1700) return ((year/100)-17);
  112.     else return (0);
  113. }
  114.  
  115. /****************************************************************************
  116.  * quad_centuries_since_1700 returns the number of xx00 years whose modulo  *
  117.  * of 400 == 0, also since 1700.                                            *
  118.  ****************************************************************************/
  119.  
  120. int quad_centuries_since_1700 (year)
  121. int    year;
  122. {
  123.     if (year > 1600) return ((year-1600)/400);
  124.     else return (0);
  125. }
  126.  
  127. /****************************************************************************
  128.  * leap_years_since_year_1 returns the number of leap years between year 1  *
  129.  * and this year *not inclusive*.                                           *
  130.  ****************************************************************************/
  131.  
  132. int leap_years_since_year_1 (year)
  133. int    year;
  134. {
  135.     --year;
  136.     return (year/4 - centuries_since_1700 (year)
  137.                    + quad_centuries_since_1700 (year));
  138. }
  139.  
  140. /****************************************************************************
  141.  * day_in_week returns a zero based day number for any date from 1 jan 1    *
  142.  * to 31 dec 9999. Assumes the gregorian reformation eliminates 3 sep 1752  *
  143.  * through 13 sep 1752. Returns THURSDAY (4) for all missing days.          *
  144.  ****************************************************************************/
  145.  
  146. int day_in_week (day, month, year)
  147. int    day;
  148. int    month;
  149. int    year;
  150. {
  151.     long    temp;
  152.  
  153.     temp = (long)(year-1)*365 + leap_years_since_year_1 (year)
  154.                   + day_in_year (day, month, year);
  155.     if (temp < FIRST_MISSING_DAY) return ((temp-1+SATURDAY)%7);
  156.     if (temp >= (FIRST_MISSING_DAY + NUMBER_MISSING_DAYS))
  157.         return (((temp-1+SATURDAY) - NUMBER_MISSING_DAYS)%7);
  158.     return (THURSDAY);
  159. }
  160.  
  161. Enjoy.
  162. --
  163. Kim Letkeman    kim@Software.Mitel.COM
  164.