/*************************************************************/
/* カレンダーの設定と出力(曜日,祝日等) */
/* 使用方法 */
/* 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;
}
}
}
}