オルタナティブ・ブログ > mtaneda ブログ >

中小企業の開発者は会社で何をしているのか

ツェラーの公式

»

曜日を求めるための公式として、「ツェラーの公式」というものがあります。

(年 + 年 ÷ 4 ー 年 ÷ 100 + 年 ÷ 400 + (13 × 月 + 8) ÷ 5 + 日) を 7で割った剰りが曜日になります。

Wikipediaが参考になります。
証明はなかなか難しいです・・・

enumの利用例としてこれを利用したカレンダーを作っていたのですが、
どうも1月2月だけ、デタラメな暦になってしまっていましたが、この公式では1月と2月は前年の13月と14月として扱う必要があるのです。
すっかり忘れていました。

 Sun Mon Tue Wed Thr Fri Sat
                          1 
  2   3   4   5   6   7   8 
  9  10  11  12  13  14  15 
 16  17  18  19  20  21  22 
 23  24  25  26  27  28  29 
 30  31 

この公式は、少しC言語ができるようになった頃MS-DOS上でグラフィックを叩いてカレンダーソフトを作った、私にとっては懐かしいものでした。
当時のプログラムをみると、かなりイケてなくて、何故うごいているかよくわからない感じでしたので、今回は新規で作ってみました。

もう少し分かりやすく書きたかったけど、目的が果たせたからいいかな・・・?という感じです。

#include

enum emonth {
  JAN = 1, FEB, MAR, APR,
  MAY,   JUN, JUL, AUG,
  SEP,   OCT, NOV, DEC
};

enum ewod {
  SUN, MON, TUE, WED, THR,
  FRI, SAT
};

int
get_week_of_day(int year, int month, int day)
{
  if (month == JAN ||
    month == FEB) {
    year--;
    month += 12;
  }

  return ((year + year / 4 - year / 100 + year / 400 + (13 * month + 8) / 5 + day) % 7);
}

int
main(int argc, char *argv[])
{
  int monthlength[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  int year, month, day, wod;

  year = 2011;

  if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0))
    monthlength[FEB] = 29;

  for (month = JAN; month <= DEC; month++) {
    wod = get_week_of_day(year, month, 1);
    day = 1 - wod;

    printf(" Sun Mon Tue Wed Thr Fri Sat\n");
    for (;day <= monthlength[month]; day++) {
      if (day <= 0 ) {
        printf("  ");
        continue;
      }
      printf("% 3d ", day);
      wod = get_week_of_day(year, month, day);
      if (wod == SAT) printf("\n");
    }
    printf("\n\n");
  }
  
  return (0);
}

Comment(0)