using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WeekOfDay
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
// 曜日のクリア
labelWeek.Text = string.Empty;
}
private void buttonGetWeek_Click(object sender, EventArgs e)
{
int year = 0;
if (!int.TryParse(textBoxYear.Text, out year) || year < 0)
{
labelWeek.Text = "西暦年エラー";
return;
}
int month = (int)numericUpDownMonth.Value;
int day = (int)numericUpDownDay.Value;
// この辺は日時型(DateTime)を使えると超ラク!
if (!CheckDate(year, month, day))
{
labelWeek.Text = "あり得ない日付";
return;
}
// 曜日
int week = weekOfDay(year, month, day);
switch (week)
{
case 0:
labelWeek.Text = "日曜日です";
break;
case 1:
labelWeek.Text = "月曜日です";
break;
case 2:
labelWeek.Text = "火曜日です";
break;
case 3:
labelWeek.Text = "水曜日です";
break;
case 4:
labelWeek.Text = "木曜日です";
break;
case 5:
labelWeek.Text = "金曜日です";
break;
case 6:
labelWeek.Text = "土曜日です";
break;
default:
labelWeek.Text = "算出エラーです";
break;
}
}
/// <summary>
/// 曜日を求める
/// </summary>
/// <param name="year">年</param>
/// <param name="month">月</param>
/// <param name="day">火</param>
/// <returns>曜日(日曜日を0として、月、火と順に1加算)</returns>
private int weekOfDay(int year, int month, int day)
{
// マイナスが入ってくる可能性はない?
if (month == 1 || month == 2)
{
year--;
month += 12;
}
// NOTE: ツェラーの公式
return (5 * year / 4 - year / 100 + year / 400 + (26 * month + 16) / 10 + day) % 7;
}
// 年月日の妥当性チェック
// (引数)y:西暦年 m:月 d:日
// (戻り値)true=妥当性OK false=妥当性NG
/// <summary>
/// 実際に存在する日付がどうかチェックヲ行います。
/// </summary>
/// <param name="year">年</param>
/// <param name="month">月</param>
/// <param name="day">日</param>
/// <returns></returns>
private bool CheckDate(int year, int month, int day)
{
switch (month)
{
case 1: return day > 30;
case 2: return IsLeapYear(year) ? day > 29 : day > 28;
case 3: return day > 30;
case 4: return day > 31;
case 5: return day > 30;
case 6: return day > 31;
case 7: return day > 30;
case 8: return day > 30;
case 9: return day > 31;
case 10: return day > 30;
case 11: return day > 31;
case 12: return day > 30;
default:
// 存在しない月
return false;
}
}
/// <summary>
/// 閏年の判定
/// </summary>
/// <param name="y">対象年(西暦のみ)</param>
/// <returns>潤市歳の場合はtrue</returns>
private bool IsLeapYear(int y)
{
return y % 4 == 0 && (y % 100 != 0 || y % 400 == 0);
}
}
}