/*************************************************************/ /* カレンダーの設定と出力(曜日,祝日等) */ /* 使用方法 */ /* cal y m : 西暦y年m月のカレンダを出力 */ /* cal y m d : 西暦y年m月d日の曜日,祝日情報を出力 */ /* (有効期間:1582年以降,ただし,祝日は別) */ /* coded by Y.Suganuma */ /*************************************************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> /************************/ /* クラスcalendarの定義 */ /************************/ class Calendar { int y, m; // 年と月 int m_d; // 一月の日数 int day[31]; // 曜日(0:日曜,・・・,6:土曜) int hol[31]; // 祝日の種類 // =-1 : 祝日でない // >=0 : 祝日番号 char h_name[5][30]; // 祝日の名前 public: Calendar(){} // コンストラクタ /**********************************/ /* クラスCalendarのコンストラクタ */ /* y_i, m_i : 年と月 */ /**********************************/ Calendar::Calendar(int y_i, int m_i) { int d, i1, k1, yo, y1, m1; /* 年と月の設定 */ y = y_i; m = m_i; /* 日にちと曜日の設定 */ // 1日の曜日 y1 = y; m1 = m; d = 1; if (m1 < 3) { y1--; m1 += 12; } yo = (y1 + (y1 / 4) - (y1 / 100) + (y1 / 400) + (13 * m1 + 8) / 5 + d) % 7; // 一月の日数 if (m == 2) { if (y%4 == 0 && y%100 != 0 || y%400 == 0) m_d = 29; else m_d = 28; } else if (m == 4 || m == 6 || m == 9 || m == 11) m_d = 30; else m_d = 31; // 各日の曜日の設定 for (i1 = 0; i1 < m_d; i1++) { day[i1] = yo; yo = (yo + 1) % 7; } /* 祝日の設定 */ for (i1 = 0; i1 < m_d; i1++) hol[i1] = -1; switch (m) { // 1月 case 1: // 元日(1月1日) hol[0] = 0; strcpy(h_name[0], "元日"); if (day[0] == 0) { hol[1] = 1; strcpy(h_name[1], "振替休日(元日)"); } // 成人の日(1月の第2月曜日) k1 = 0; for (i1 = 0; i1 < m_d && k1 < 2; i1++) { if (day[i1] == 1) { k1++; if (k1 == 2) { hol[i1] = 2; strcpy(h_name[2], "成人の日"); } } } break; // 2月 case 2: // 建国記念日(2月11日) hol[10] = 0; strcpy(h_name[0], "建国記念日"); if (day[10] == 0) { hol[11] = 1; strcpy(h_name[1], "振替休日(建国記念日)"); } break; // 3月 case 3: // 春分の日(3月20日頃) if (y < 2100) d = (int)(20.8431 + 0.242194 * (y - 1980) - (y - 1980) / 4) - 1; else d = (int)(21.8510 + 0.242194 * (y - 1980) - (y - 1980) / 4) - 1; hol[d] = 0; strcpy(h_name[0], "春分の日"); if (day[d] == 0) { hol[d+1] = 1; strcpy(h_name[1], "振替休日(春分の日)"); } break; // 4月 case 4: // みどりの日(4月29日) hol[28] = 0; strcpy(h_name[0], "みどりの日"); if (day[28] == 0) { hol[29] = 1; strcpy(h_name[1], "振替休日(みどりの日)"); } break; // 5月 case 5: // 憲法記念日,国民の休日,こどもの日(5月3,4,5日) hol[2] = 0; strcpy(h_name[0], "憲法記念日"); hol[3] = 1; strcpy(h_name[1], "国民の休日"); hol[4] = 2; strcpy(h_name[2], "こどもの日"); if (day[4] == 0) { hol[5] = 3; strcpy(h_name[3], "振替休日(こどもの日)"); } break; // 6月 case 6: break; // 7月 case 7: // 海の日(7月20日) hol[19] = 0; strcpy(h_name[0], "海の日"); if (day[19] == 0) { hol[20] = 1; strcpy(h_name[1], "振替休日(海の日)"); } break; // 8月 case 8: break; // 9月 case 9: // 敬老の日(9月15日) hol[14] = 0; strcpy(h_name[0], "敬老の日"); if (day[14] == 0) { hol[15] = 1; strcpy(h_name[1], "振替休日(敬老の日)"); } // 秋分の日(9月23日頃) if (y < 2100) d = (int)(23.2488 + 0.242194 * (y - 1980) - (y - 1980) / 4) - 1; else d = (int)(24.2488 + 0.242194 * (y - 1980) - (y - 1980) / 4) - 1; hol[d] = 2; strcpy(h_name[2], "秋分の日"); if (day[d] == 0) { hol[d+1] = 3; strcpy(h_name[3], "振替休日(秋分の日)"); } break; // 10月 case 10: // 体育の日(10月の第2月曜日) k1 = 0; for (i1 = 0; i1 < m_d && k1 < 2; i1++) { if (day[i1] == 1) { k1++; if (k1 == 2) { hol[i1] = 0; strcpy(h_name[0], "体育の日"); } } } break; // 11月 case 11: // 文化の日(11月3日) hol[2] = 0; strcpy(h_name[0], "文化の日"); if (day[2] == 0) { hol[3] = 1; strcpy(h_name[1], "振替休日(文化の日)"); } // 勤労感謝の日(11月23日) hol[22] = 2; strcpy(h_name[2], "勤労感謝の日"); if (day[22] == 0) { hol[23] = 3; strcpy(h_name[3], "振替休日(勤労感謝の日)"); } break; // 12月 case 12: // 天皇誕生日(12月23日) hol[22] = 0; strcpy(h_name[0], "天皇誕生日"); if (day[22] == 0) { hol[23] = 1; strcpy(h_name[1], "振替休日(天皇誕生日)"); } break; } } /*****************************************/ /* 日にち情報の取得 */ /* d : 日にち */ /* sw : =0 : 祝日でない */ /* =1 : 祝日 */ /* name : 祝日の名前 */ /* return : 曜日(0:日,・・・,6:土) */ /* (-1:エラー) */ /*****************************************/ int Calendar::Inf_day(int d, int *sw, char name[]) { int yo = -1; if (d < 1 || d > m_d) { printf("***error 日にちが不適当です\n"); exit(1); } d--; *sw = 0; yo = day[d]; if (hol[d] >= 0) { *sw = 1; strcpy(name, h_name[hol[d]]); } return yo; } /********************/ /* カレンダーの出力 */ /* 下線は祝日 */ /*******************/ void Calendar::Out_cal() { int i1, i2, k = 0, k1; printf(" 日 月 火 水 木 金 土\n\n"); while (k < day[0]) { printf(" "); k++; } k1 = -day[0]; for (i1 = 0; i1 < m_d; i1++) { printf(" %2d", i1+1); k++; if (k == 7 || i1 == m_d-1) { printf("\n"); for (i2 = 0; i2 < 7 && k1 <= m_d-1; i2++) { if (k1 >= 0) { if (hol[k1] < 0) printf(" "); else printf("  ̄"); } else printf(" "); k1++; } printf("\n"); k = 0; k1 = i1 + 1; } } } }; /****************/ /* main program */ /****************/ int main(int argc, char *argv[]) { int y, m, d, yo, sw; char name[30]; char y_n[7][7] = {"日曜日", "月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日"}; // 引数の数のチェック if (argc != 3 && argc != 4) { printf("***error 年,月等を入力してください\n"); exit(1); } // 引数の数OK else { // 年,月のチェック y = atoi(argv[1]); if (y < 2001 || y > 2150) { printf("***error 2001≦年≦2150\n"); exit(1); } m = atoi(argv[2]); if (m < 1 || m > 12) { printf("***error 月が不適当です\n"); exit(1); } // 年,月の値OK Calendar cal(y, m); // 日にち情報の取得 if (argc == 4) { d = atoi(argv[3]); yo = cal.Inf_day(d, &sw, name); if (yo >= 0) { printf("%d年%d月%d日 %s", y, m, d, y_n[yo]); if (sw == 0) printf("\n"); else printf(" %s\n", name); } } // カレンダーの出力 else cal.Out_cal(); } return 0; }