カレンダーの設定と出力(曜日,祝日等)

/*************************************************************/
/* カレンダーの設定と出力(曜日,祝日等)                    */
/*      使用方法                                             */
/*           cal y m : 西暦y年m月のカレンダを出力            */
/*           cal y m d : 西暦y年m月d日の曜日,祝日情報を出力 */
/*          (有効期間:1582年以降,ただし,祝日は別)       */
/*      coded by Y.Suganuma                                  */
/************************************************************/
import java.io.*;

/**************/
/* クラスTest */
/**************/
public class Test {
	public static void main(String args[]) throws IOException
	{
		int y, m, d, yo, sw[] = new int [1];
		String name[] = new String [1];
		String y_n[] = {"日曜日", "月曜日", "火曜日", "水曜日",
                        "木曜日", "金曜日", "土曜日"};
						// 引数の数のチェック
		if (args.length != 2 && args.length != 3) {
			System.out.println("***error  年,月等を入力してください");
			System.exit(1);
		}
						// 引数の数OK
		else {
							// 年,月のチェック
			y = Integer.parseInt(args[0]);
			if (y < 2001 || y > 2150) {
				System.out.println("***error  2001≦年≦2150");
				System.exit(1);
			}
			m = Integer.parseInt(args[1]);
			if (m < 1 || m > 12) {
				System.out.println("***error  月が不適当です");
				System.exit(1);
			}
							// 年,月の値OK
			Calendar cal = new Calendar (y, m);
								// 日にち情報の取得
			if (args.length == 3) {
				d  = Integer.parseInt(args[2]);
				yo = cal.Inf_day(d, sw, name);
				if (yo >= 0) {
					System.out.print(y + "年" + m + "月" + d + "日 " + y_n[yo]);
					if (sw[0] == 0)
						System.out.println();
					else
						System.out.println(" " + name[0]);
				}
			}
								// カレンダーの出力
			else
				cal.Out_cal();
		}
	}
}

/************************/
/* クラスcalendarの定義 */
/************************/
class Calendar {
	private int y, m;   // 年と月
	private int m_d;   // 一月の日数
	private int day[] = new int [31];   // 曜日(0:日曜,・・・,6:土曜)
	private int hol[] = new int [31];   // 祝日の種類
                                        //   =-1 : 祝日でない
                                        //   >=0 : 祝日番号
	private String h_name[] = new String [5];   // 祝日の名前

	/******************/
	/* コンストラクタ */
	/******************/
	Calendar(){}

	/**********************************/
	/* クラスCalendarのコンストラクタ */
	/*      y_i, m_i : 年と月         */
	/**********************************/
	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;
				h_name[0] = "元日";
				if (day[0] == 0) {
					hol[1]    = 1;
					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;
							h_name[2] = "成人の日";
						}
					}
				}
				break;
						// 2月
			case 2:
							// 建国記念日(2月11日)
				hol[10]   = 0;
				h_name[0] = "建国記念日";
				if (day[10] == 0) {
					hol[11]   = 1;
					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;
				h_name[0] = "春分の日";
				if (day[d] == 0) {
					hol[d+1]  = 1;
					h_name[1] = "振替休日(春分の日)";
				}
				break;
						// 4月
			case 4:
							// みどりの日(4月29日)
				hol[28]   = 0;
				h_name[0] = "みどりの日";
				if (day[28] == 0) {
					hol[29]   = 1;
					h_name[1] = "振替休日(みどりの日)";
				}
				break;
						// 5月
			case 5:
							// 憲法記念日,国民の休日,こどもの日(5月3,4,5日)
				hol[2]    = 0;
				h_name[0] = "憲法記念日";
				hol[3]    = 1;
				h_name[1] = "国民の休日";
				hol[4]    = 2;
				h_name[2] = "こどもの日";
				if (day[4] == 0) {
					hol[5]    = 3;
					h_name[3] = "振替休日(こどもの日)";
				}
				break;
						// 6月
			case 6:
				break;
						// 7月
			case 7:
							// 海の日(7月20日)
				hol[19]   = 0;
				h_name[0] = "海の日";
				if (day[19] == 0) {
					hol[20]   = 1;
					h_name[1] = "振替休日(海の日)";
				}
				break;
						// 8月
			case 8:
				break;
						// 9月
			case 9:
							// 敬老の日(9月15日)
				hol[14]   = 0;
				h_name[0] = "敬老の日";
				if (day[14] == 0) {
					hol[15]   = 1;
					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;
				h_name[2] = "秋分の日";
				if (day[d] == 0) {
					hol[d+1]  = 3;
					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;
							h_name[0] = "体育の日";
						}
					}
				}
				break;
						// 11月
			case 11:
							// 文化の日(11月3日)
				hol[2]    = 0;
				h_name[0] = "文化の日";
				if (day[2] == 0) {
					hol[3]    = 1;
					h_name[1] = "振替休日(文化の日)";
				}
							// 勤労感謝の日(11月23日)
				hol[22]   = 2;
				h_name[2] = "勤労感謝の日";
				if (day[22] == 0) {
					hol[23]   = 3;
					h_name[3] = "振替休日(勤労感謝の日)";
				}
				break;
						// 12月
			case 12:
							// 天皇誕生日(12月23日)
				hol[22]   = 0;
				h_name[0] = "天皇誕生日";
				if (day[22] == 0) {
					hol[23]   = 1;
					h_name[1] = "振替休日(天皇誕生日)";
				}
				break;
		}
	}

	/*****************************************/
	/* 日にち情報の取得                      */
	/*      d : 日にち                       */
	/*      sw : =0 : 祝日でない             */
	/*           =1 : 祝日                   */
	/*      name : 祝日の名前                */
	/*      return : 曜日(0:日,・・・,6:土) */
	/*               (-1:エラー)            */
	/*****************************************/
	int Inf_day(int d, int sw[], String name[])
	{
		int yo = -1;

		if (d < 1 || d > m_d) {
			System.out.println("***error  日にちが不適当です");
			System.exit(1);
		}

		d--;
		sw[0] = 0;
		yo    = day[d];
		if (hol[d] >= 0) {
			sw[0]   = 1;
			name[0] = h_name[hol[d]];
		}

		return yo;
	}

	/********************/
	/* カレンダーの出力 */
	/*      下線は祝日  */
	/********************/
	void Out_cal()
	{
		int i1, i2, k = 0, k1;

		System.out.print(" 日 月 火 水 木 金 土\n\n");

		while (k < day[0]) {
			System.out.print("   ");
			k++;
		}

		k1 = -day[0];
		for (i1 = 0; i1 < m_d; i1++) {
			if (i1 > 8)
				System.out.print(" " + (i1+1));
			else
				System.out.print("  " + (i1+1));
			k++;
			if (k == 7 || i1 == m_d-1) {
				System.out.print("\n");
				for (i2 = 0; i2 < 7 && k1 <= m_d-1; i2++) {
					if (k1 >= 0) {
						if (hol[k1] < 0)
							System.out.print("   ");
						else
							System.out.print("  ̄");
					}
					else
						System.out.print("   ");
					k1++;
				}
				System.out.print("\n");
				k  = 0;
				k1 = i1 + 1;
			}
		}
	}
}