#include #include /* atoi */ #include /* time */ long greg2jd(int year, int month, int day); int weeknumber(int year, int month, int day); /* 月の名前。デフォルトがラテン語なのは単なる気まぐれ */ char* title[2] = { /* " April May June July August September", */ " Aprilis Maius Junius Quintilis Sextilis September", /* " October November December January February March" */ " October November December Januarius Februarius Martius" }; /* 日付。「四月から九月」「十月から翌年三月(平年版)」「同(閏年版)」の順 */ char* days[3][7] = { { " 1 8 15 22 29 6 13 20 27 3 10 17 24 1 8 15 22 29 5 12 19 26 2 9 16 23 30", " 2 9 16 23 30 7 14 21 28 4 11 18 25 2 9 16 23 30 6 13 20 27 3 10 17 24", " 3 10 17 24 1 8 15 22 29 5 12 19 26 3 10 17 24 31 7 14 21 28 4 11 18 25", " 4 11 18 25 2 9 16 23 30 6 13 20 27 4 11 18 25 1 8 15 22 29 5 12 19 26", " 5 12 19 26 3 10 17 24 31 7 14 21 28 5 12 19 26 2 9 16 23 30 6 13 20 27", " 6 13 20 27 4 11 18 25 1 8 15 22 29 6 13 20 27 3 10 17 24 31 7 14 21 28", " 7 14 21 28 5 12 19 26 2 9 16 23 30 7 14 21 28 4 11 18 25 1 8 15 22 29" }, { " 1 8 15 22 29 5 12 19 26 3 10 17 24 31 7 14 21 28 4 11 18 25 4 11 18 25", " 2 9 16 23 30 6 13 20 27 4 11 18 25 1 8 15 22 29 5 12 19 26 5 12 19 26", " 3 10 17 24 31 7 14 21 28 5 12 19 26 2 9 16 23 30 6 13 20 27 6 13 20 27", " 4 11 18 25 1 8 15 22 29 6 13 20 27 3 10 17 24 31 7 14 21 28 7 14 21 28", " 5 12 19 26 2 9 16 23 30 7 14 21 28 4 11 18 25 1 8 15 22 1 8 15 22 29", " 6 13 20 27 3 10 17 24 1 8 15 22 29 5 12 19 26 2 9 16 23 2 9 16 23 30", " 7 14 21 28 4 11 18 25 2 9 16 23 30 6 13 20 27 3 10 17 24 3 10 17 24 31" }, { " 1 8 15 22 29 5 12 19 26 3 10 17 24 31 7 14 21 28 4 11 18 25 3 10 17 24 31", " 2 9 16 23 30 6 13 20 27 4 11 18 25 1 8 15 22 29 5 12 19 26 4 11 18 25", " 3 10 17 24 31 7 14 21 28 5 12 19 26 2 9 16 23 30 6 13 20 27 5 12 19 26", " 4 11 18 25 1 8 15 22 29 6 13 20 27 3 10 17 24 31 7 14 21 28 6 13 20 27", " 5 12 19 26 2 9 16 23 30 7 14 21 28 4 11 18 25 1 8 15 22 29 7 14 21 28", " 6 13 20 27 3 10 17 24 1 8 15 22 29 5 12 19 26 2 9 16 23 1 8 15 22 29", " 7 14 21 28 4 11 18 25 2 9 16 23 30 6 13 20 27 3 10 17 24 2 9 16 23 30" } }; int main(int argc, char* argv[]) { int year, wday, isleap; int i, j; if (argc > 1) { /* 年をセット。三月までは前年とする */ year = atoi(argv[1]); } else { time_t now = time(NULL); year = localtime(&now)->tm_year + 1900 - (localtime(&now)->tm_mon < 3); } wday = (greg2jd(year, 4, 1) + 1) % 7; /* 四月 1 日の曜日 */ if (wday == 0) { /* 本プログラムでは日曜日は 7 とする */ wday = 7; } /* year の翌年の二月が表示されることに注意 */ isleap = !((year+1) % 4) && (year+1) % 100 || !((year+1) % 400); puts(title[0]); /* 四月から十月までの表示が始まる */ for (i=0; i<7; i++) { if (i < wday - 1) { printf(" "); /* 左端のすきま */ } puts(days[0][(i+8-wday)%7]); /* 日付の表示 */ } printf("--------------------------------------------------------------------------------\n"); i = weeknumber(year, 4, 1); j = weeknumber(year, 9, 24); /* なぜこの日なのかは自分で考えよ */ while (i <= j) { printf("%2d%s", i, i 0) { return ret; } } } return 99; /* 警告封じのための unreachable code */ } /****************************************************************************** 【関数名】 greg2jd() 【機 能】 グレゴリウス暦からユリウス日への換算。 【引 数】 年、月、日。 【注意0】 ここでいうグレゴリウス暦とは、現行のグレゴリウス暦をその実施以前に までさかのぼって延長したものである。 【注意1】 紀元前の年の呼び方は、1 年の前年を 0 年とする天文学上の規約に従う。 引数は -4713 年 11 月 24 日(ユリウス日 0 の日)以降、桁あふれが 生じる直前まで有効である。実際には -4800 年 03 月 01 日以降に対し 正しいユリウス日を返すと思うが、あまり意味がないだろう。 【注意2】 最初に 4800 を足すのは閏年か平年かを変えずに考えるべき全ての年を正 にするため。最後の 32045 は“魔法の数”。 【注意3】 Zeller の公式の変形である。 【注意4】 ユリウス日に 1 を加えてから 7 で割った余りを求めれば曜日(0 が 日曜日、1 が月曜日、……、6 が土曜日)が得られる。 ******************************************************************************/ long greg2jd(int year, int month, int day) { year += 4800; if (month < 3) { year--; month += 12; } return 365L * year + year / 4 - year / 100 + year / 400 \ + (153 * month - 457) / 5 + day - 32045; }