msp0310
4/12/2017 - 3:11 PM

refactored.cs

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);
        }
    }
}