Calendario personalizado del día de la diosa de TI y calendario lunar

Hoy es el Día de la Diosa, aquí hay un calendario que muestra la fecha actual y el calendario lunar, así como festivales especiales

1. Crear una nueva aplicación de formulario CustomCalendarDemo

Cambie el nombre del Form1 predeterminado a FormCustomDate y el formulario FormCustomDate se diseñará como se muestra en la figura:

 2. El código del diseñador de formularios es el siguiente (FormCustomDate.Designer.cs):


namespace CustomCalendarDemo
{
    partial class FormCustomDate
    {
        /// <summary>
        /// 必需的设计器变量。
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// 清理所有正在使用的资源。
        /// </summary>
        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows 窗体设计器生成的代码

        /// <summary>
        /// 设计器支持所需的方法 - 不要修改
        /// 使用代码编辑器修改此方法的内容。
        /// </summary>
        private void InitializeComponent()
        {
            this.cboYear = new System.Windows.Forms.ComboBox();
            this.cboMonth = new System.Windows.Forms.ComboBox();
            this.dgvDate = new System.Windows.Forms.DataGridView();
            this.rtbInfo = new System.Windows.Forms.RichTextBox();
            this.Column1 = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.Column2 = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.Column3 = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.Column4 = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.Column5 = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.Column6 = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.Column7 = new System.Windows.Forms.DataGridViewTextBoxColumn();
            ((System.ComponentModel.ISupportInitialize)(this.dgvDate)).BeginInit();
            this.SuspendLayout();
            // 
            // cboYear
            // 
            this.cboYear.FormattingEnabled = true;
            this.cboYear.Location = new System.Drawing.Point(27, 12);
            this.cboYear.Name = "cboYear";
            this.cboYear.Size = new System.Drawing.Size(157, 20);
            this.cboYear.TabIndex = 0;
            this.cboYear.SelectedIndexChanged += new System.EventHandler(this.cboYear_SelectedIndexChanged);
            // 
            // cboMonth
            // 
            this.cboMonth.FormattingEnabled = true;
            this.cboMonth.Location = new System.Drawing.Point(215, 12);
            this.cboMonth.Name = "cboMonth";
            this.cboMonth.Size = new System.Drawing.Size(121, 20);
            this.cboMonth.TabIndex = 1;
            this.cboMonth.SelectedIndexChanged += new System.EventHandler(this.cboMonth_SelectedIndexChanged);
            // 
            // dgvDate
            // 
            this.dgvDate.AllowUserToAddRows = false;
            this.dgvDate.AllowUserToDeleteRows = false;
            this.dgvDate.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            this.dgvDate.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
            this.Column1,
            this.Column2,
            this.Column3,
            this.Column4,
            this.Column5,
            this.Column6,
            this.Column7});
            this.dgvDate.Location = new System.Drawing.Point(12, 49);
            this.dgvDate.Name = "dgvDate";
            this.dgvDate.ReadOnly = true;
            this.dgvDate.RowTemplate.Height = 23;
            this.dgvDate.Size = new System.Drawing.Size(787, 375);
            this.dgvDate.TabIndex = 2;
            this.dgvDate.CellEnter += new System.Windows.Forms.DataGridViewCellEventHandler(this.dgvDate_CellEnter);
            // 
            // rtbInfo
            // 
            this.rtbInfo.Location = new System.Drawing.Point(12, 439);
            this.rtbInfo.Name = "rtbInfo";
            this.rtbInfo.Size = new System.Drawing.Size(787, 239);
            this.rtbInfo.TabIndex = 3;
            this.rtbInfo.Text = "";
            // 
            // Column1
            // 
            this.Column1.HeaderText = "星期日";
            this.Column1.Name = "Column1";
            this.Column1.ReadOnly = true;
            // 
            // Column2
            // 
            this.Column2.HeaderText = "星期一";
            this.Column2.Name = "Column2";
            this.Column2.ReadOnly = true;
            // 
            // Column3
            // 
            this.Column3.HeaderText = "星期二";
            this.Column3.Name = "Column3";
            this.Column3.ReadOnly = true;
            // 
            // Column4
            // 
            this.Column4.HeaderText = "星期三";
            this.Column4.Name = "Column4";
            this.Column4.ReadOnly = true;
            // 
            // Column5
            // 
            this.Column5.HeaderText = "星期四";
            this.Column5.Name = "Column5";
            this.Column5.ReadOnly = true;
            // 
            // Column6
            // 
            this.Column6.HeaderText = "星期五";
            this.Column6.Name = "Column6";
            this.Column6.ReadOnly = true;
            // 
            // Column7
            // 
            this.Column7.HeaderText = "星期六";
            this.Column7.Name = "Column7";
            this.Column7.ReadOnly = true;
            // 
            // FormCustomDate
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(819, 708);
            this.Controls.Add(this.rtbInfo);
            this.Controls.Add(this.dgvDate);
            this.Controls.Add(this.cboMonth);
            this.Controls.Add(this.cboYear);
            this.Name = "FormCustomDate";
            this.Text = "自制日历-显示农历";
            this.Load += new System.EventHandler(this.FormCustomDate_Load);
            ((System.ComponentModel.ISupportInitialize)(this.dgvDate)).EndInit();
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.ComboBox cboYear;
        private System.Windows.Forms.ComboBox cboMonth;
        private System.Windows.Forms.DataGridView dgvDate;
        private System.Windows.Forms.RichTextBox rtbInfo;
        private System.Windows.Forms.DataGridViewTextBoxColumn Column1;
        private System.Windows.Forms.DataGridViewTextBoxColumn Column2;
        private System.Windows.Forms.DataGridViewTextBoxColumn Column3;
        private System.Windows.Forms.DataGridViewTextBoxColumn Column4;
        private System.Windows.Forms.DataGridViewTextBoxColumn Column5;
        private System.Windows.Forms.DataGridViewTextBoxColumn Column6;
        private System.Windows.Forms.DataGridViewTextBoxColumn Column7;
    }
}

3. Cree un nuevo archivo de clase ChinaDate, que se utiliza para mostrar la descripción del calendario lunar chino y la información del festival:

El programa fuente de ChinaDate.cs es el siguiente:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CustomCalendarDemo
{
    /// <summary>
    /// 获取中国农历信息,
    /// 关键类:ChineseLunisolarCalendar
    /// </summary>
    public static class ChinaDate
    {
        private static ChineseLunisolarCalendar china = new ChineseLunisolarCalendar();
        private static Hashtable gHoliday = new Hashtable();
        private static Hashtable nHoliday = new Hashtable();
        private static string[] JQ = { "小寒", "大寒", "立春", "雨水", "惊蛰", "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至", "小暑", "大暑", "立秋", "处暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "冬至" };
        private static int[] JQData = { 0, 21208, 43467, 63836, 85337, 107014, 128867, 150921, 173149, 195551, 218072, 240693, 263343, 285989, 308563, 331033, 353350, 375494, 397447, 419210, 440795, 462224, 483532, 504758 };

        static ChinaDate()
        {
            //公历节日
            gHoliday.Add("0101", "元旦");
            gHoliday.Add("0214", "情人节");
            gHoliday.Add("0305", "雷锋日");
            gHoliday.Add("0308", "妇女节");
            gHoliday.Add("0312", "植树节");
            gHoliday.Add("0315", "消费者权益日");
            gHoliday.Add("0401", "愚人节");
            gHoliday.Add("0501", "劳动节");
            gHoliday.Add("0504", "青年节");
            gHoliday.Add("0601", "儿童节");
            gHoliday.Add("0701", "建党节");
            gHoliday.Add("0801", "建军节");
            gHoliday.Add("0910", "教师节");
            gHoliday.Add("0918", "九一八纪念日");
            gHoliday.Add("0930", "烈士纪念日");
            gHoliday.Add("1001", "国庆节");
            gHoliday.Add("1213", "国家公祭日");
            //gHoliday.Add("1224", "平安夜");
            gHoliday.Add("1225", "圣诞节");

            //农历节日
            nHoliday.Add("0101", "春节");
            nHoliday.Add("0115", "元宵节");
            nHoliday.Add("0505", "端午节");
            nHoliday.Add("0815", "中秋节");
            nHoliday.Add("0909", "重阳节");
            nHoliday.Add("1208", "腊八节");
        }

        /// <summary>
        /// 获取农历
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static string GetChinaDate(DateTime dt)
        {
            if (dt > china.MaxSupportedDateTime || dt < china.MinSupportedDateTime)
            {
                //日期范围:1901 年 2 月 19 日 - 2101 年 1 月 28 日
                throw new Exception(string.Format("日期超出范围!必须在{0}到{1}之间!", china.MinSupportedDateTime.ToString("yyyy-MM-dd"), china.MaxSupportedDateTime.ToString("yyyy-MM-dd")));
            }
            string str = string.Format("{0}{1}{2}", GetYear(dt), GetMonth(dt), GetDay(dt));
            string strJQ = GetSolarTerm(dt);
            if (strJQ != "")
            {
                str += " (" + strJQ + ")";
            }
            string strHoliday = GetHoliday(dt);
            if (strHoliday != "")
            {
                str += " " + strHoliday;
            }
            string strChinaHoliday = GetChinaHoliday(dt);
            if (strChinaHoliday != "")
            {
                str += " " + strChinaHoliday;
            }

            return str;
        }

        /// <summary>
        /// 获取农历年份
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static string GetYear(DateTime dt)
        {
            int yearIndex = china.GetSexagenaryYear(dt);
            string yearTG = " 甲乙丙丁戊己庚辛壬癸";
            string yearDZ = " 子丑寅卯辰巳午未申酉戌亥";
            string yearSX = " 鼠牛虎兔龙蛇马羊猴鸡狗猪";
            int year = china.GetYear(dt);
            int yTG = china.GetCelestialStem(yearIndex);
            int yDZ = china.GetTerrestrialBranch(yearIndex);

            string str = string.Format("生肖:【{0}】\n{1}{2}年", yearSX[yDZ], yearTG[yTG], yearDZ[yDZ]);
            return str;
        }

        /// <summary>
        /// 获取农历月份
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static string GetMonth(DateTime dt)
        {
            int year = china.GetYear(dt);
            int iMonth = china.GetMonth(dt);
            int leapMonth = china.GetLeapMonth(year);
            bool isLeapMonth = iMonth == leapMonth;
            if (leapMonth != 0 && iMonth == leapMonth)
            {
                iMonth--;
            }

            string szText = "正二三四五六七八九十";
            string strMonth = isLeapMonth ? "闰" : "";
            if (iMonth <= 10)
            {
                strMonth += szText.Substring(iMonth - 1, 1);
            }
            else if (iMonth == 11)
            {
                strMonth += "十一";
            }
            else
            {
                strMonth += "腊";
            }
            return strMonth + "月";
        }

        /// <summary>
        /// 获取农历日期
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static string GetDay(DateTime dt)
        {
            int iDay = china.GetDayOfMonth(dt);
            string szText1 = "初十廿三";
            string szText2 = "一二三四五六七八九十";
            string strDay;
            if (iDay == 20)
            {
                strDay = "二十";
            }
            else if (iDay == 30)
            {
                strDay = "三十";
            }
            else
            {
                strDay = szText1.Substring((iDay - 1) / 10, 1);
                strDay = strDay + szText2.Substring((iDay - 1) % 10, 1);
            }
            return strDay;
        }

        /// <summary>
        /// 获取节气
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static string GetSolarTerm(DateTime dt)
        {
            DateTime dtBase = new DateTime(1900, 1, 6, 2, 5, 0);
            DateTime dtNew;
            double num;
            int y;
            string strReturn = "";

            y = dt.Year;
            for (int i = 1; i <= 24; i++)
            {
                num = 525948.76 * (y - 1900) + JQData[i - 1];
                dtNew = dtBase.AddMinutes(num);
                if (dtNew.DayOfYear == dt.DayOfYear)
                {
                    strReturn = JQ[i - 1];
                }
            }

            return strReturn;
        }

        /// <summary>
        /// 获取公历节日
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static string GetHoliday(DateTime dt)
        {
            string strReturn = "";
            object g = gHoliday[dt.Month.ToString("00") + dt.Day.ToString("00")];
            if (g != null)
            {
                strReturn = g.ToString();
            }

            return strReturn;
        }

        /// <summary>
        /// 获取农历节日
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static string GetChinaHoliday(DateTime dt)
        {
            string strReturn = "";
            int year = china.GetYear(dt);
            int iMonth = china.GetMonth(dt);
            int leapMonth = china.GetLeapMonth(year);
            int iDay = china.GetDayOfMonth(dt);
            if (china.GetDayOfYear(dt) == china.GetDaysInYear(year))
            {
                strReturn = "除夕";
            }
            else if (leapMonth != iMonth)
            {
                if (leapMonth != 0 && iMonth == leapMonth)
                {
                    iMonth--;
                }
                object n = nHoliday[iMonth.ToString("00") + iDay.ToString("00")];
                if (n != null)
                {
                    if (strReturn == "")
                    {
                        strReturn = n.ToString();
                    }
                    else
                    {
                        strReturn += " " + n.ToString();
                    }
                }
            }

            return strReturn;
        }
    }
}

4. El programa fuente del formulario FormCustomDate (FormCustomDate.cs) es el siguiente:

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 CustomCalendarDemo
{
    public partial class FormCustomDate : Form
    {
        //是否激活下拉框选择内容的改变事件全部加载基本内容后再激活
        bool enabledSelectedEvent = false;

        public FormCustomDate()
        {
            InitializeComponent();
            rtbInfo.ReadOnly = true;
        }

        /// <summary>
        /// 初始化数据设置年的范围为~2099年之间
        /// </summary>
        private void InitialData()
        {
            //年
            DataTable dt = new DataTable("XX");
            dt.Columns.Add("ID", typeof(int));
            dt.Columns.Add("Name", typeof(string));
            for (int i = 1980; i < 2100; i++)
            {
                dt.Rows.Add(i, i + "年");
            }
            cboYear.DataSource = dt;
            cboYear.DisplayMember = "Name";
            cboYear.ValueMember = "ID";

            //月
            DataTable dtMonth = dt.Clone();
            dtMonth.Rows.Add(1, "一月");
            dtMonth.Rows.Add(2, "二月");
            dtMonth.Rows.Add(3, "三月");
            dtMonth.Rows.Add(4, "四月");
            dtMonth.Rows.Add(5, "五月");
            dtMonth.Rows.Add(6, "六月");
            dtMonth.Rows.Add(7, "七月");
            dtMonth.Rows.Add(8, "八月");
            dtMonth.Rows.Add(9, "九月");
            dtMonth.Rows.Add(10, "十月");
            dtMonth.Rows.Add(11, "十一月");
            dtMonth.Rows.Add(12, "十二月");
            cboMonth.DataSource = dtMonth;
            cboMonth.DisplayMember = "Name";
            cboMonth.ValueMember = "ID";
        }

        /// <summary>
        /// 显示某年某月的日历
        /// </summary>
        /// <param name="year"></param>
        /// <param name="month"></param>
        private void DisplayDate(int year, int month)
        {
            dgvDate.Rows.Clear();
            DateTime firstDay = new DateTime(year, month, 1);
            int columnIndex = (int)firstDay.DayOfWeek;
            int maxDay = GetMaxDay(year, month);
            //某月的第一天的星期数对应列的索引即当月天数需要额外增加columnIndex
            //当月总天数设定为:columnIndex+maxDay。总分页数:(x+(n-1))/n 其中n=7
            //表格共有行数:(columnIndex+maxDay+6)/7 取整
            int day = 1;
            for (int i = 0; i < (columnIndex + maxDay + 6) / 7; i++)
            {
                int index = dgvDate.Rows.Add();
                for (int j = 0; j < 7; j++)
                {
                    if (i == 0) //第一行从对应的星期开始填写
                    {
                        if (j >= columnIndex)
                        {
                            dgvDate[j, index].Value = day;
                            day++;
                        }
                    }
                    else
                    {
                        dgvDate[j, index].Value = day;
                        day++;
                        if (day > maxDay)
                        {
                            break;
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 获得某年某月有多少天
        /// </summary>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        private int GetMaxDay(int year, int month)
        {
            bool isLeapYear = DateTime.IsLeapYear(year);
            switch (month)
            {
                case 1:
                case 3:
                case 5:
                case 7:
                case 8:
                case 10:
                case 12:
                    return 31;
                case 4:
                case 6:
                case 9:
                case 11:
                    return 30;
                case 2:
                    return isLeapYear ? 29 : 28;
                default:
                    return 0;
            }
        }

        /// <summary>
        /// 获得星期的中文描述
        /// </summary>
        /// <param name="week"></param>
        /// <returns></returns>
        private string GetWeekDay(DayOfWeek week)
        {
            switch (week)
            {
                case DayOfWeek.Sunday:
                    return "星期日";
                case DayOfWeek.Monday:
                    return "星期一";
                case DayOfWeek.Tuesday:
                    return "星期二";
                case DayOfWeek.Wednesday:
                    return "星期三";
                case DayOfWeek.Thursday:
                    return "星期四";
                case DayOfWeek.Friday:
                    return "星期五";
                case DayOfWeek.Saturday:
                    return "星期六";
                default:
                    return "";
            }
        }

        private void FormCustomDate_Load(object sender, EventArgs e)
        {
            //只能选择一个单元格、列不可排序
            dgvDate.MultiSelect = false;
            for (int i = 0; i < 7; i++)
            {
                dgvDate.Columns[i].SortMode = DataGridViewColumnSortMode.NotSortable;
            }
            InitialData();
            //默认为当前年月
            DateTime currentDate = DateTime.Now;
            for (int i = 0; i < cboYear.Items.Count; i++)
            {
                DataRowView drv = cboYear.Items[i] as DataRowView;
                if (Convert.ToInt32(drv.Row["ID"]) == currentDate.Year)
                {
                    cboYear.SelectedIndex = i;
                    break;
                }
            }
            for (int i = 0; i < cboMonth.Items.Count; i++)
            {
                DataRowView drv = cboMonth.Items[i] as DataRowView;
                if (Convert.ToInt32(drv.Row["ID"]) == currentDate.Month)
                {
                    cboMonth.SelectedIndex = i;
                    break;
                }
            }

            DisplayDate(currentDate.Year, currentDate.Month);
            for (int i = 0; i < dgvDate.Rows.Count; i++)
            {
                bool isBreak = false;
                for (int j = 0; j < 7; j++)
                {
                    if (Convert.ToString(dgvDate[j, i].Value) == currentDate.Day.ToString())
                    {
                        isBreak = true;
                        dgvDate[j, i].Selected = true;
                        break;
                    }
                }
                if (isBreak)
                {
                    break;
                }
            }
            //D2: 格式化为位数字不足位则前面补0
            DisplayContents(currentDate);
            enabledSelectedEvent = true;
        }

        private void DisplayContents(DateTime currentDate) 
        {
            //显示 癸卯年闰二月初五
            rtbInfo.Text = string.Format("当前日期:{0}年{1:D2}月{2:D2}日 {3}\n{4}",
                currentDate.Year, currentDate.Month, currentDate.Day,
                GetWeekDay(currentDate.DayOfWeek), ChinaDate.GetChinaDate(currentDate));            
        }

        private void cboYear_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (enabledSelectedEvent)
            {
                DisplayDate(Convert.ToInt32(cboYear.SelectedValue), Convert.ToInt32(cboMonth.SelectedValue));
            }
        }

        private void cboMonth_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (enabledSelectedEvent)
            {
                DisplayDate(Convert.ToInt32(cboYear.SelectedValue), Convert.ToInt32(cboMonth.SelectedValue));
            }
        }

        private void dgvDate_CellEnter(object sender, DataGridViewCellEventArgs e)
        {
            if (dgvDate.SelectedCells.Count < 1)
                return;
            object day = dgvDate.SelectedCells[0].Value;
            if (Convert.ToInt32(day) > 0)
            {
                DateTime currentDate = new DateTime(Convert.ToInt32(cboYear.SelectedValue),
                    Convert.ToInt32(cboMonth.SelectedValue), Convert.ToInt32(day));
                DisplayContents(currentDate);
            }
            else //没有选择日历的单元格
            {
                rtbInfo.Text = "";
            }
        }
    }
}

5. El programa se ejecuta como se muestra en la figura:

 

 

Supongo que te gusta

Origin blog.csdn.net/ylq1045/article/details/129410874
Recomendado
Clasificación