天天看點

WindowsPhone 中 根據公曆 擷取農曆日期資料WindowsPhone 中 根據公曆 擷取農曆日期資料

WindowsPhone 中 根據公曆 擷取農曆日期資料

WindowsPhone 中 自定義 類,根據公曆 擷取農曆日期資料

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


namespace ChineseCalendar
{
    /// <summary>
    /// 中國農曆
    /// </summary>
    public static class ChineseDate
    {
        #region 月曆資料
        /// <summary>
        /// int[] CalendarData
        /// </summary>
        static int[] CalendarData = new int[] {
                    0x41A95, 0xD4A, 0xDA5, 0x20B55, 0x56A, 0x7155B,
                    0x25D, 0x92D, 0x5192B, 0xA95, 0xB4A, 0x416AA, 0xAD5,
                    0x90AB5, 0x4BA, 0xA5B, 0x60A57, 0x52B, 0xA93, 0x40E95 };


        /// <summary>
        /// int[] madd
        /// </summary>
        static int[] madd = new int[] { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };


        static String numString = "一二三四五六七八九十";
        static String monString = "正二三四五六七八九十冬臘";
        static String[] run = new String[] { "閏正", "閏二", "閏三", "閏四", "閏五", "閏六", "閏七", "閏八", "閏九", "閏十", "閏冬", "閏臘" };
        static String cDateString = String.Empty;
        static int cYear, cMonth, cDay, cHour;
        static String holiday = String.Empty;
        #endregion


        #region 節日資料
        /// <summary>
        /// 農曆節日資料
        /// </summary>
        static String[] NLHoliday = new String[] { 
                "正月初一 春節",
                "正月十五 元宵節",
                "二月初二 龍擡頭",
                "五月初五 端午節",
                "七月初七 七夕",
                "七月十五 中元節",
                "八月十五 中秋節",
                "九月初九 重陽節",
                "臘月初八 臘八節",
                "臘月廿三 小年",
                "臘月三十 除夕"
        };


        //公曆節日 表示放假日
        static String[] GLHoliday = new String[] {
                "0101 元旦",
                "0214 情人節",
                "0308 婦女節",
                "0312 植樹節",
                "0401 愚人節",
                "0422 地球日",
                "0501 勞動節",
                "0504 青年節",
                "0531 無煙日",
                "0601 兒童節",
                "0606 愛眼日",
                "0701 建黨日",
                "0707 抗戰紀念日",
                "0801 建軍節",
                "0910 教師節",
                "0918 九一八事變",
                "1001 國慶節",
                "1031 萬聖節",
                "1111 光棍節",
                "1201 艾滋病日",
                "1213 南京大屠殺紀念日",
                "1224 平安夜",
                "1225 聖誕節"
        };
        #endregion


        #region 計算方法
        /// <summary>
        /// int GetBit
        /// </summary>
        /// <param name="m"></param>
        /// <param name="n"></param>
        /// <returns></returns>
        private static int GetBit(int m, int n)
        {
            return (m >> n) & 1;
        }




        /// <summary>
        /// void e2c
        /// </summary>
        /// <param name="dt">公曆時間</param>
        private static void e2c(DateTime dt)
        {
            bool isEnd = false;
            int total, m, n, k, tmp = dt.Year;

            if (tmp < 1900) tmp += 1900;

            total = (tmp - 2001) * 365
                  + (int)Math.Floor((Double)(tmp - 2001) / 4)
                  + madd[dt.Month - 1]
                  + dt.Day
                  - 23;

            if (dt.Year % 4 == 0 && dt.Month > 2)
                total++;

            for (m = 0; ; m++)
            {
                k = (CalendarData[m] < 0xfff) ? 11 : 12;
                for (n = k; n >= 0; n--)
                {
                    if (total <= 29 + GetBit(CalendarData[m], n))
                    {
                        isEnd = true;
                        break;
                    }
                    total = total - 29 - GetBit(CalendarData[m], n);
                }
                if (isEnd) break;
            }


            cYear = 2001 + m;
            cMonth = k - n + 1;
            cDay = total;

            if (k == 12)
            {
                if (cMonth == (int)Math.Floor((double)(CalendarData[m] / 0x10000) + 1))
                    cMonth = 1 - cMonth;


                if (cMonth > (int)Math.Floor((double)(CalendarData[m] / 0x10000) + 1))
                    cMonth--;
            }
            cHour = (int)Math.Floor((double)((dt.Hour + 3) / 2));
        }


        /// <summary>
        /// void GetcDateString()
        /// </summary>
        private static void GetcDateString()
        {
            String tmp = String.Empty;

            if (cMonth < 1)
            {
                tmp += "閏";
                tmp += monString[-cMonth - 1];
            }
            else tmp += monString[cMonth - 1] + "月";

            if (cDay <= 10) tmp += "初";
            else if (cDay < 20) tmp += "十";
            else if (cDay == 20) tmp += "二十";
            else if (cDay < 30) tmp += "廿";
            else tmp += "三十";

            if (cDay % 10 != 0 || cDay == 10)
                tmp += numString[Math.Abs(cDay - 1) % 10];

            cDateString = tmp;
        }


        /// <summary>
        /// 擷取對應日期的節日資料
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="strDate"></param>
        private static void getHoliday(DateTime dt, String strDate)
        {
            //擷取農曆節日
            String strNLHoliday = String.Empty;
            if (strDate == "正月")
                strNLHoliday = "春節";
            else
            {
                for (int i = 0, len = NLHoliday.Length; i < len; i++)
                {
                    if (NLHoliday[i].ToString().Contains(strDate))
                    {
                        strNLHoliday = NLHoliday[i].ToString().Split(' ')[1];
                        break;
                    }
                }
            }

            //擷取公曆節日
            String strGLHoliday = String.Empty;
            for (int i = 0, len = GLHoliday.Length; i < len; i++)
            {
                if (GLHoliday[i].ToString().Contains(dt.ToString("MMdd")))
                {
                    strGLHoliday = GLHoliday[i].ToString().Split(' ')[1];
                    break;
                }
            }

            //傳回結果
            if (!String.IsNullOrEmpty(strNLHoliday) && !String.IsNullOrEmpty(strGLHoliday))
                holiday = (strNLHoliday + strGLHoliday).Replace("節", "");
            else if (!String.IsNullOrEmpty(strNLHoliday))
                holiday = strNLHoliday;
            else if (!String.IsNullOrEmpty(strGLHoliday))
                holiday = strGLHoliday;
            else holiday = String.Empty;
        }



        #region 農曆年
        /// <summary>
        /// 十天幹
        /// </summary>
        private static string[] tiangan = { "甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸" };

        /// <summary>
        /// 十二地支
        /// </summary>
        private static string[] dizhi = { "子", "醜", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥" };


        /// <summary>
        /// 十二生肖
        /// </summary>
        private static string[] shengxiao = { "鼠", "牛", "虎", "免", "龍", "蛇", "馬", "羊", "猴", "雞", "狗", "豬" };

        /// <summary>
        /// 傳回農曆天幹地支年 
        /// </summary>
        /// <param name="year">農曆年</param>
        /// <returns></returns>
        private static string GetLunisolarYear(int year)
        {
            int tgIndex = (year - 1900 + 36) % 10;
            int dzIndex = (year - 1900 + 36) % 12;


            return string.Concat(tiangan[tgIndex], dizhi[dzIndex], "【", shengxiao[dzIndex], "】");
        }
        #endregion
        #endregion


        #region 調用方法
        /// <summary>
        /// 擷取農曆日期(格式 dd)
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static String getNLDate(DateTime dt)
        {
            e2c(dt);
            GetcDateString();

            //擷取節日
            getHoliday(dt, cDateString);

            if (cDateString.Contains("初一"))
                cDateString = cDateString.Replace("初一", "");
            else
                cDateString = cDateString.Substring(cDateString.IndexOf("月") + 1);

            for (int i = 0, len = run.Length; i < len; i++)
            {
                if (cDateString.Contains(run[i]))
                {
                    cDateString = cDateString.Replace(run[i], "");
                    if (String.IsNullOrEmpty(cDateString))
                        cDateString = run[i];


                    break;
                }
            }

            return cDateString;
        }


        /// <summary>
        /// 擷取農曆日期(格式 年月日完整日期)
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static String getNLDateTime(DateTime dt)
        {
            //農曆月
            getNLDate(dt);


            return GetLunisolarYear(dt.Year) + "年" + cDateString;
        }


        /// <summary>
        /// 擷取節日資料
        /// </summary>
        /// <returns></returns>
        public static String getHoliday()
        {
            return holiday;
        }
        #endregion
    }
}
           

備注:此類 是更根據網上的 javascript 改編而來。

            經過測試,當輸入的公曆 年 小于 2001 年 擷取的農曆日期資料就會有誤,

            并且 當 輸入的年 大于 2040 年後 擷取的農曆資料也會有誤!

          希望有人能夠完善。謝謝!

效果圖:

WindowsPhone 中 根據公曆 擷取農曆日期資料WindowsPhone 中 根據公曆 擷取農曆日期資料

繼續閱讀