Пример #1
0
        /// <summary>
        /// 命理八字计算(普通计算, 不转换为当地真太阳时), 并保存到日对象 ob 中
        /// </summary>
        /// <param name="jd">格林尼治UT(J2000起算)</param>
        /// <param name="J">本地经度</param>
        /// <param name="ob">日对象</param>
        /// <param name="southernHemisphere">南半球的标志</param>
        public static void mingLiBaZiNormal(double jd, double J, OB ob, BaZiTypeS baziTypeS)
        {
            int    i;
            string c;
            double v;
            double jd2 = jd + JD.deltatT2(jd);                                               // 力学时
            double w   = XL.S_aLon(jd2 / 36525, -1);                                         // 此刻太阳视黄经
            double k   = LunarHelper.int2((w / LunarHelper.pi2 * 360 + 45 + 15 * 360) / 30); // 1984年立春起算的节气数(不含中气)

            //----------------------------------------------------------------------------------------------
            // C#: 注: 仅有下列代码段与 mingLiBaZi 方法中的代码不同, 其余部分都是相同的
            //----------------------------------------------------------------------------------------------
            jd       += 0 - J / Math.PI / 2;                                 // 将格林尼治UT(J2000起算), 转换为本地时间, 不必考虑真太阳与平太阳时之间的时差
            ob.bz_zty = "";                                                  // 真太阳时置空串
            ob.bz_pty = JD.timeStr(jd);                                      // 计算平太阳时

            jd += 13d / 24d;                                                 // 转为前一日23点起算(原jd为本日中午12点起算)   // C#: 注意数据类型
            double D = Math.Floor(jd), SC = LunarHelper.int2((jd - D) * 12); // 日数与时辰

            v = LunarHelper.int2(k / 12 + 6000000); ob.bz_jn = obb.Gan[(int)(v % 10)] + obb.Zhi[(int)(v % 12)];
            v = k + 2 + 60000000; ob.bz_jy = obb.Gan[(int)(v % 10)] + obb.Zhi[(int)(v % 12)];

            // C#: 新增的代码段, 计算南半球八字(仅纪月不同)
            switch (baziTypeS)
            {
            case BaZiTypeS.TianChongDiChong:
                ob.bz_jy = obb.Gan[(int)((v + 4) % 10)] + obb.Zhi[(int)((v + 6) % 12)];
                break;

            case BaZiTypeS.TianKeDiChong:
                ob.bz_jy = obb.Gan[(int)((v + 6) % 10)] + obb.Zhi[(int)((v + 6) % 12)];
                break;

            case BaZiTypeS.TianTongDiChong:
                ob.bz_jy = obb.Gan[(int)((v + 0) % 10)] + obb.Zhi[(int)((v + 6) % 12)];
                break;

            default:
                break;
            }


            v = D - 6 + 9000000; ob.bz_jr = obb.Gan[(int)(v % 10)] + obb.Zhi[(int)(v % 12)];
            v = (D - 1) * 12 + 90000000 + SC; ob.bz_js = obb.Gan[(int)(v % 10)] + obb.Zhi[(int)(v % 12)];

            v       -= SC;
            ob.bz_JS = "";    // 全天纪时表
            for (i = 0; i < 13; i++)
            {
                // 一天中包含有13个纪时
                c = obb.Gan[(int)((v + i) % 10)] + obb.Zhi[(int)((v + i) % 12)];  // 各时辰的八字
                if (SC == i)
                {
                    ob.bz_js = c;
                    // c = "<font color=red>" + c + "</font>";   //红色显示这时辰   // C#: 注释, 即取消格式显示
                }
                ob.bz_JS += (i != 0 ? " " : "") + c;
            }
        }
Пример #2
0
        /// <summary>
        /// 计算某日节日的信息, 并保存信息到日对象中
        /// </summary>
        /// <param name="u">日对象</param>
        /// <param name="r">日对象</param>
        public static void getDayName(OB u, OB r)
        {
            string m0 = (u.m < 10 ? "0" : "") + u.m;
            string d0 = (u.d < 10 ? "0" : "") + u.d;
            int i;
            string s, s2, type;

            if (u.week == 0 || u.week == 6)
                r.Fjia = 1;   // 星期日或星期六放假

            // 按公历日期查找
            for (i = 0; i < oba.sFtv[u.m - 1].Length; i++)    // C#: 注: 属性 sFtv 在初始化时已经包含了 12 个元素, 以对应 12 个月
            {
                // 公历节日或纪念日,遍历本月节日表
                s = oba.sFtv[u.m - 1][i];
                if (s.Length < 3 || s.Substring(0, 2) != d0)    // C#: 新增了第 1 个判断条件
                    continue;
                s = s.Substring(2, s.Length - 2);
                type = s.Substring(0, 1);
                if (s.Length >= 6 && s.Substring(5, 1) == "-")
                {
                    // 有年限的节日
                    if (u.y < (int.Parse(s.Substring(1, 4))) || u.y > (int.Parse(s.Substring(6, 4)))) continue;
                    s = s.Substring(10, s.Length - 10);
                }
                else
                {
                    if (u.y < 1850) continue;
                    s = s.Substring(1, s.Length - 1);
                }
                if (type == "#") { r.A += s + " "; r.Fjia = 1; } //放假的节日
                if (type == "I") r.B += s + " "; //主要
                if (type == ".") r.C += s + " "; //其它
            }

            // 按周规则查找
            double w = u.weeki;
            if (u.week >= u.week0) w += 1;
            double w2 = w;
            if (u.weeki == u.weekN - 1) w2 = 5;
            string w__ = m0 + w + u.week;    // d日在本月的第几个星期某
            string w2__ = m0 + w2 + u.week;

            for (i = 0; i < oba.wFtv.Length; i++)
            {
                s = oba.wFtv[i];
                s2 = s.Substring(0, 4);
                if (s2 != w__ && s2 != w2__) continue;
                type = s.Substring(4, 1);
                s = s.Substring(5, s.Length - 5);
                if (type == "#") { r.A += s + " "; r.Fjia = 1; }
                if (type == "I") r.B += s + " ";
                if (type == ".") r.C += s + " ";
            }
        }
Пример #3
0
        /// <summary>
        /// 回历计算, 并保存信息到日对象中
        /// </summary>
        /// <param name="d0">2000.0起算儒略日,北京时12:00</param>
        /// <param name="r">日对象</param>
        public static void getHuiLi(double d0, OB r)
        {
            // 以下算法使用Excel测试得到,测试时主要关心年临界与月临界
            double z, y, m, d;

            d        = d0 + 503105; z = LunarHelper.int2((d + 0.1) / 10631);                          // 10631为一周期(30年)
            d       -= z * 10631; y = LunarHelper.int2((d + 0.5) / 354.366);                          // 加0.5的作用是保证闰年正确(一周中的闰年是第2,5,7,10,13,16,18,21,24,26,29年)
            d       -= LunarHelper.int2(y * 354.366 + 0.5); m = LunarHelper.int2((d + 0.11) / 29.51); // 分子加0.11,分每加0.01的作用是第354或355天的的月分保持为12月(m=11)
            d       -= LunarHelper.int2(m * 29.51 + 0.5);
            r.Hyear  = z * 30 + y + 1;
            r.Hmonth = m + 1;
            r.Hday   = d + 1;
        }
Пример #4
0
        /// <summary>
        /// 计算八字
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="ob">日对象</param>
        /// <param name="type">八字类型</param>
        /// <param name="curTZ">时区</param>
        /// <param name="year">年</param>
        /// <param name="month">月</param>
        /// <param name="day">日</param>
        /// <param name="time">时间串</param>
        /// <param name="longitudeStr">经度(度分秒格式)</param>
        /// <returns>八字字符串</returns>
        public static string ML_calc <T>(OB ob, BaZiType type, double curTZ, T year, T month, T day, string time, string longitudeStr, BaZiTypeS baziTypes)
        {
            double y = LunarHelper.year2Ayear(year);

            if (y == -10000)
            {
                return(String.Empty);
            }

            string timeName = (type == BaZiType.ZtyBaZi ? "真太阳 " :
                               (type == BaZiType.PtyBaZi ? "平太阳 " : "北京时间 "));

            double t = LunarHelper.timeStr2hour(time);

            double longitude;

            if (type == BaZiType.EL120BaZi)
            {
                longitude = LunarHelper.str2rad("-120°");    // 解析东经120°经度为弧度
            }
            else
            {
                longitude = LunarHelper.str2rad(longitudeStr);    // 解析经度为弧度
            }
            double jd = JD.JD__(y, LunarHelper.VAL(month.ToString()),
                                LunarHelper.VAL(day.ToString()) + t / 24);

            if (type == BaZiType.ZtyBaZi)
            {
                obb.mingLiBaZi(jd + curTZ / 24 - LunarHelper.J2000, longitude, ob, baziTypes);    // 八字计算, 独立于 Lunar 类
                timeName += ob.bz_zty;
            }
            else
            {
                obb.mingLiBaZiNormal(jd + curTZ / 24 - LunarHelper.J2000, longitude, ob, baziTypes);    // 八字计算, 独立于 Lunar 类
                timeName += ob.bz_pty;
            }

            // C#: 新增的代码段
            JD.setFromJD(jd);
            double yearAjusted  = JD.Y;
            double monthAjusted = JD.M;
            double dayAjusted   = JD.D;

            return("[日标]:" + "公历 " + yearAjusted + "-" + monthAjusted + "-" + dayAjusted + " 儒略日数 " + LunarHelper.int2(jd + 0.5) +
                   " 距2000年首" + LunarHelper.int2(jd + 0.5 - LunarHelper.J2000) + "日"
                   + "\r\n[八字]:" + ob.bz_jn + "年 " + ob.bz_jy + "月 " + ob.bz_jr + "日 " + ob.bz_js + "时 " + timeName
                   + "\r\n[纪时]:" + ob.bz_JS
                   + "\r\n[时标]:" + "23  01  03  05  07  09  11  13  15  17  19  21  23");
        }
Пример #5
0
        /// <summary>
        /// 指定某日, 计算出它的所属节(气), 上一节(气), 下一节(气)信息, 并把计算结果保存在日对象中
        /// </summary>
        /// <param name="ob"></param>
        /// <returns>计算成功返回 true, 否则返回 false </returns>
        public bool CalcJieQiInfo(OB ob, CalcJieQiType calcType)
        {
            const int JiQiInfo_Name             = 0;
            const int JiQiInfo_JDTime           = 1;
            const int JiQiInfo_Time             = 2;
            const int JiQiInfo_HistoricalJDTime = 3;
            const int JiQiInfo_HistoricalTime   = 4;
            const int JiQiInfo_DifferentTime    = 5;
            const int JiQiInfo_JieOrQi          = 6;
            const int JiQiInfo_YueJian          = 7;
            const int JiQiInfo_DayDifference    = 8;

            const int PrevJieQiFlag = 0;
            const int ThisJieQiFlag = 1;
            const int NextJieQiFlag = 2;

            double    y = ob.y;
            int       j, counter = 0, thisJie = -1, jieQiPos = 0;
            JieQiInfo jieqiInfo;

            int[] jieqiInfoPos = new int[3];
            object[,] jieqiList = new object[31, 9];

            double v, qi = 0;

            int num = SSQ.calcJieQi(LunarHelper.int2((y - 2000) * 365.2422 + 180), true); // 计算节气, 以"霜降"开始

            for (j = 0; j < num; j++)                                                     // 建表
            {
                if (calcType == CalcJieQiType.CalcJie)                                    // 只计算节
                {
                    if (((j + 24) % 24) % 2 == 0)                                         // 气(跳过, 只使用节)
                    {
                        continue;
                    }
                }

                if (calcType == CalcJieQiType.CalcQi)    // 只计算气
                {
                    if (((j + 24) % 24) % 2 == 1)        // 节(跳过, 只使用气)
                    {
                        continue;
                    }
                }

                qi = SSQ.ZQ[j];

                v = obb.qi_accurate2(qi);
                jieqiList[counter, JiQiInfo_Time] = JD.setFromJD_str(v + LunarHelper.J2000);

                jieQiPos = (j + 24) % 24 + 20;      // 与 obb.jqmc 对应, "霜降"距首位"冬至"的距离为 20
                if (jieQiPos >= 24)
                {
                    jieQiPos -= 24;
                }

                jieqiList[counter, JiQiInfo_JieOrQi] = true;
                jieqiList[counter, JiQiInfo_Name]    = obb.jqmc[jieQiPos];
                jieqiList[counter, JiQiInfo_YueJian] = obb.JieQiYueJian[jieQiPos];
                jieqiList[counter, JiQiInfo_JDTime]  = v + LunarHelper.J2000;

                jieqiList[counter, JiQiInfo_HistoricalTime]   = JD.setFromJD_str(qi + LunarHelper.J2000);
                jieqiList[counter, JiQiInfo_HistoricalJDTime] = qi + LunarHelper.J2000;
                jieqiList[counter, JiQiInfo_DifferentTime]    = (LunarHelper.int2(v + 0.5) != qi ? true : false);

                jieqiList[counter, JiQiInfo_DayDifference] = (int)(LunarHelper.int2(v + 0.5) - qi);

                counter++;
            }

            for (j = 0; j < SSQ.ZQ.Count; j++)    // △重要: 由于调用了 SSQ.calcJieQi 方法, 计算了 31 个节气(超出年周期)数据, 故应清零
            {
                SSQ.ZQ[j] = 0;
            }

            if (ob.y >= 0)
            {
                int ymd = ob.y * 10000 + ob.m * 100 + ob.d; // 转换成为数值表示的日期: 如 20090422
                for (j = counter - 1; j >= 0; j--)          // 逆序查表(表中的交节日期数据是由小到大排列的)
                {
                    string jieqiTime  = (string)jieqiList[j, JiQiInfo_Time];
                    int    jieqiYear  = int.Parse(jieqiTime.Substring(0, 5));
                    int    jieqiMonth = int.Parse(jieqiTime.Substring(6, 2));
                    int    jieqiDay   = int.Parse(jieqiTime.Substring(9, 2));
                    if (jieqiYear * 10000 + jieqiMonth * 100 + jieqiDay <= ymd)    // 找到所属的节气
                    {
                        thisJie = j;
                        break;
                    }
                }
            }
            else
            {
                int ymd = ob.y * 10000 - (99 - ob.m) * 100 - (99 - ob.d);
                for (j = 0; j < counter; j++)    // 顺序查表(表中的交节日期数据是由小到大排列的, 计算为数值时也要严格递增)
                {
                    string jieqiTime  = (string)jieqiList[j, JiQiInfo_Time];
                    int    jieqiYear  = int.Parse(jieqiTime.Substring(0, 5));
                    int    jieqiMonth = int.Parse(jieqiTime.Substring(6, 2));
                    int    jieqiDay   = int.Parse(jieqiTime.Substring(9, 2));
                    int    jieqiYmd   = jieqiYear * 10000 - (99 - jieqiMonth) * 100 - (99 - jieqiDay);
                    if (jieqiYmd >= ymd)
                    {
                        if (jieqiYmd > ymd)
                        {
                            thisJie = j - 1;
                        }
                        else
                        {
                            thisJie = j;
                        }
                        break;
                    }
                }
            }

            if (thisJie > 0 && thisJie < counter)
            {
                jieqiInfoPos[ThisJieQiFlag] = thisJie;
                jieqiInfoPos[PrevJieQiFlag] = jieqiInfoPos[ThisJieQiFlag] - 1;
                jieqiInfoPos[NextJieQiFlag] = jieqiInfoPos[ThisJieQiFlag] + 1;

                for (j = 0; j < jieqiInfoPos.Length; j++)
                {
                    switch (j)
                    {
                    case PrevJieQiFlag:
                        jieqiInfo = ob.PreviousJieQi;
                        break;

                    case ThisJieQiFlag:
                        jieqiInfo = ob.ThisJieQi;
                        break;

                    case NextJieQiFlag:
                        jieqiInfo = ob.NextJieQi;
                        break;

                    default:
                        jieqiInfo = null;
                        break;
                    }

                    if (jieqiInfo != null)
                    {
                        jieqiInfo.JieOrQi = (bool)jieqiList[jieqiInfoPos[j], JiQiInfo_JieOrQi];
                        jieqiInfo.Name    = (string)jieqiList[jieqiInfoPos[j], JiQiInfo_Name];
                        jieqiInfo.YueJian = (string)jieqiList[jieqiInfoPos[j], JiQiInfo_YueJian];
                        jieqiInfo.Time    = (string)jieqiList[jieqiInfoPos[j], JiQiInfo_Time];
                        jieqiInfo.JDTime  = (double)jieqiList[jieqiInfoPos[j], JiQiInfo_JDTime];

                        jieqiInfo.HistoricalTime   = (string)jieqiList[jieqiInfoPos[j], JiQiInfo_HistoricalTime];
                        jieqiInfo.HistoricalJDTime = (double)jieqiList[jieqiInfoPos[j], JiQiInfo_HistoricalJDTime];
                        jieqiInfo.DifferentTime    = (bool)jieqiList[jieqiInfoPos[j], JiQiInfo_DifferentTime];

                        jieqiInfo.DayDifference = (int)jieqiList[jieqiInfoPos[j], JiQiInfo_DayDifference];
                    }
                }

                return(true);
            }

            return(false);
        }
Пример #6
0
        /// <summary>
        /// 命理八字计算(普通计算, 不转换为当地真太阳时), 并保存到日对象 ob 中
        /// </summary>
        /// <param name="jd">格林尼治UT(J2000起算)</param>
        /// <param name="J">本地经度</param>
        /// <param name="ob">日对象</param>
        /// <param name="southernHemisphere">南半球的标志</param>
        public static void mingLiBaZiNormal(double jd, double J, OB ob, BaZiTypeS baziTypeS)
        {
            int i;
            string c;
            double v;
            double jd2 = jd + JD.deltatT2(jd);      // 力学时
            double w = XL.S_aLon(jd2 / 36525, -1);  // 此刻太阳视黄经
            double k = LunarHelper.int2((w / LunarHelper.pi2 * 360 + 45 + 15 * 360) / 30);   // 1984年立春起算的节气数(不含中气)

            //----------------------------------------------------------------------------------------------
            // C#: 注: 仅有下列代码段与 mingLiBaZi 方法中的代码不同, 其余部分都是相同的
            //----------------------------------------------------------------------------------------------
            jd += 0 - J / Math.PI / 2;     // 将格林尼治UT(J2000起算), 转换为本地时间, 不必考虑真太阳与平太阳时之间的时差
            ob.bz_zty = "";                // 真太阳时置空串
            ob.bz_pty = JD.timeStr(jd);    // 计算平太阳时

            jd += 13d / 24d;   // 转为前一日23点起算(原jd为本日中午12点起算)   // C#: 注意数据类型
            double D = Math.Floor(jd), SC = LunarHelper.int2((jd - D) * 12);   // 日数与时辰

            v = LunarHelper.int2(k / 12 + 6000000); ob.bz_jn = obb.Gan[(int)(v % 10)] + obb.Zhi[(int)(v % 12)];
            v = k + 2 + 60000000; ob.bz_jy = obb.Gan[(int)(v % 10)] + obb.Zhi[(int)(v % 12)];

            // C#: 新增的代码段, 计算南半球八字(仅纪月不同)
            switch (baziTypeS)
            {
                case BaZiTypeS.TianChongDiChong:
                    ob.bz_jy = obb.Gan[(int)((v + 4) % 10)] + obb.Zhi[(int)((v + 6) % 12)];
                    break;

                case BaZiTypeS.TianKeDiChong:
                    ob.bz_jy = obb.Gan[(int)((v + 6) % 10)] + obb.Zhi[(int)((v + 6) % 12)];
                    break;

                case BaZiTypeS.TianTongDiChong:
                    ob.bz_jy = obb.Gan[(int)((v + 0) % 10)] + obb.Zhi[(int)((v + 6) % 12)];
                    break;

                default:
                    break;
            }

            v = D - 6 + 9000000; ob.bz_jr = obb.Gan[(int)(v % 10)] + obb.Zhi[(int)(v % 12)];
            v = (D - 1) * 12 + 90000000 + SC; ob.bz_js = obb.Gan[(int)(v % 10)] + obb.Zhi[(int)(v % 12)];

            v -= SC;
            ob.bz_JS = "";    // 全天纪时表
            for (i = 0; i < 13; i++)
            {
                // 一天中包含有13个纪时
                c = obb.Gan[(int)((v + i) % 10)] + obb.Zhi[(int)((v + i) % 12)];  // 各时辰的八字
                if (SC == i)
                {
                    ob.bz_js = c;
                    // c = "<font color=red>" + c + "</font>";   //红色显示这时辰   // C#: 注释, 即取消格式显示
                }
                ob.bz_JS += (i != 0 ? " " : "") + c;
            }
        }
Пример #7
0
 /// <summary>
 /// 命理八字计算(普通计算, 不转换为当地真太阳时), 并保存到日对象 ob 中
 /// </summary>
 /// <param name="jd">格林尼治UT(J2000起算)</param>
 /// <param name="J">本地经度</param>
 /// <param name="ob">日对象</param>
 public static void mingLiBaZiNormal(double jd, double J, OB ob)
 {
     mingLiBaZiNormal(jd, J, ob, BaZiTypeS.Normal);
 }
Пример #8
0
        /// <summary>
        /// 计算农历节日
        /// </summary>
        /// <param name="u"></param>
        /// <param name="r"></param>
        public static void getDayName(OB u, OB r)
        {
            int i;

            // 按农历日期查找重点节假日
            string d = u.Lmc + (u.Lmc.Length < 2 ? "月" : "") + u.Ldc;
            if (u.Lleap != "闰")
            {
                for (i = 0; i < obb.LunarFeasts.Length; i++)     // C#: 查表, 查找农历节假日
                {
                    if (d == obb.LunarFeasts[i].Lmc)
                    {
                        r.A += obb.LunarFeasts[i].A;
                        r.B += obb.LunarFeasts[i].B;
                        r.C += obb.LunarFeasts[i].C;
                        r.Fjia = obb.LunarFeasts[i].Fjia;
                    }
                }
            }
            if (u.Lmc2 == "正")
            {
                // 最后一月
                if (d == "十二三十" && u.Ldn == 30) { r.A += "除夕 "; r.Fjia = 1; }
                if (d == "十二廿九" && u.Ldn == 29) { r.A += "除夕 "; r.Fjia = 1; }
                if (d == "十二廿三") r.B += "小年 ";
            }
            if (u.Ljq.Length > 0)
            {
                for (i = 0; i < obb.JieQiFeasts.Length; i++)    // C#: 查找是否有放假的节气
                {
                    if (u.Ljq == obb.JieQiFeasts[i])               // C#: 匹配
                        break;
                }
                if (i < obb.JieQiFeasts.Length) { r.A += u.Ljq + " "; r.Fjia = 1; }
                else r.B += u.Ljq + " ";
            }

            // 农历杂节
            string w, w2;
            if (u.cur_dz >= 0 && u.cur_dz < 81)
            { // 数九
                w = obb.numCn[(int)Math.Floor(u.cur_dz / 9) + 1];
                if (u.cur_dz % 9 == 0) r.B += "『" + w + "九』 ";
                else r.C += w + "九第" + (u.cur_dz % 9 + 1) + "天 ";
            }

            w = u.Lday2.Substring(0, 1);
            w2 = u.Lday2.Substring(1, 1);
            if (u.cur_xz > 20 && u.cur_xz <= 30 && w == "庚") r.B += "初伏 ";
            if (u.cur_xz > 30 && u.cur_xz <= 40 && w == "庚") r.B += "中伏 ";
            if (u.cur_lq > 0 && u.cur_lq <= 10 && w == "庚") r.B += "末伏 ";
            if (u.cur_mz > 0 && u.cur_mz <= 10 && w == "丙") r.B += "入梅 ";
            if (u.cur_xs > 0 && u.cur_xs <= 12 && w2 == "未") r.B += "出梅 ";
        }
Пример #9
0
 /// <summary>
 /// 命理八字计算(普通计算, 不转换为当地真太阳时), 并保存到日对象 ob 中
 /// </summary>
 /// <param name="jd">格林尼治UT(J2000起算)</param>
 /// <param name="J">本地经度</param>
 /// <param name="ob">日对象</param>
 public static void mingLiBaZiNormal(double jd, double J, OB ob)
 {
     mingLiBaZiNormal(jd, J, ob, BaZiTypeS.Normal);
 }
Пример #10
0
        /// <summary>
        /// 计算农历节日
        /// </summary>
        /// <param name="u"></param>
        /// <param name="r"></param>
        public static void getDayName(OB u, OB r)
        {
            int i;

            // 按农历日期查找重点节假日
            string d = u.Lmc + (u.Lmc.Length < 2 ? "月" : "") + u.Ldc;

            if (u.Lleap != "闰")
            {
                for (i = 0; i < obb.LunarFeasts.Length; i++)     // C#: 查表, 查找农历节假日
                {
                    if (d == obb.LunarFeasts[i].Lmc)
                    {
                        r.A   += obb.LunarFeasts[i].A;
                        r.B   += obb.LunarFeasts[i].B;
                        r.C   += obb.LunarFeasts[i].C;
                        r.Fjia = obb.LunarFeasts[i].Fjia;
                    }
                }
            }
            if (u.Lmc2 == "正")
            {
                // 最后一月
                if (d == "十二三十" && u.Ldn == 30)
                {
                    r.A += "除夕 "; r.Fjia = 1;
                }
                if (d == "十二廿九" && u.Ldn == 29)
                {
                    r.A += "除夕 "; r.Fjia = 1;
                }
                if (d == "十二廿三")
                {
                    r.B += "小年 ";
                }
            }
            if (u.Ljq.Length > 0)
            {
                for (i = 0; i < obb.JieQiFeasts.Length; i++)    // C#: 查找是否有放假的节气
                {
                    if (u.Ljq == obb.JieQiFeasts[i])            // C#: 匹配
                    {
                        break;
                    }
                }
                if (i < obb.JieQiFeasts.Length)
                {
                    r.A += u.Ljq + " "; r.Fjia = 1;
                }
                else
                {
                    r.B += u.Ljq + " ";
                }
            }

            // 农历杂节
            string w, w2;

            if (u.cur_dz >= 0 && u.cur_dz < 81)
            { // 数九
                w = obb.numCn[(int)Math.Floor(u.cur_dz / 9) + 1];
                if (u.cur_dz % 9 == 0)
                {
                    r.B += "『" + w + "九』 ";
                }
                else
                {
                    r.C += w + "九第" + (u.cur_dz % 9 + 1) + "天 ";
                }
            }

            w  = u.Lday2.Substring(0, 1);
            w2 = u.Lday2.Substring(1, 1);
            if (u.cur_xz > 20 && u.cur_xz <= 30 && w == "庚")
            {
                r.B += "初伏 ";
            }
            if (u.cur_xz > 30 && u.cur_xz <= 40 && w == "庚")
            {
                r.B += "中伏 ";
            }
            if (u.cur_lq > 0 && u.cur_lq <= 10 && w == "庚")
            {
                r.B += "末伏 ";
            }
            if (u.cur_mz > 0 && u.cur_mz <= 10 && w == "丙")
            {
                r.B += "入梅 ";
            }
            if (u.cur_xs > 0 && u.cur_xs <= 12 && w2 == "未")
            {
                r.B += "出梅 ";
            }
        }
Пример #11
0
        /// <summary>
        /// 指定某日, 计算出它的所属节(气), 上一节(气), 下一节(气)信息, 并把计算结果保存在日对象中
        /// </summary>
        /// <param name="ob"></param>
        /// <returns>计算成功返回 true, 否则返回 false </returns>
        public bool CalcJieQiInfo(OB ob, CalcJieQiType calcType)
        {
            const int JiQiInfo_Name = 0;
            const int JiQiInfo_JDTime = 1;
            const int JiQiInfo_Time = 2;
            const int JiQiInfo_HistoricalJDTime = 3;
            const int JiQiInfo_HistoricalTime = 4;
            const int JiQiInfo_DifferentTime = 5;
            const int JiQiInfo_JieOrQi = 6;
            const int JiQiInfo_YueJian = 7;
            const int JiQiInfo_DayDifference = 8;

            const int PrevJieQiFlag = 0;
            const int ThisJieQiFlag = 1;
            const int NextJieQiFlag = 2;

            double y = ob.y;
            int j, counter = 0, thisJie = -1, jieQiPos = 0;
            JieQiInfo jieqiInfo;
            int[] jieqiInfoPos = new int[3];
            object[,] jieqiList = new object[31, 9];

            double v, qi = 0;

            int num = SSQ.calcJieQi(LunarHelper.int2((y - 2000) * 365.2422 + 180), true);    // 计算节气, 以"霜降"开始

            for (j = 0; j < num; j++)    // 建表
            {
                if (calcType == CalcJieQiType.CalcJie)   // 只计算节
                    if (((j + 24) % 24) % 2 == 0)           // 气(跳过, 只使用节)
                        continue;

                if (calcType == CalcJieQiType.CalcQi)    // 只计算气
                    if (((j + 24) % 24) % 2 == 1)           // 节(跳过, 只使用气)
                        continue;

                qi = SSQ.ZQ[j];

                v = obb.qi_accurate2(qi);
                jieqiList[counter, JiQiInfo_Time] = JD.setFromJD_str(v + LunarHelper.J2000);

                jieQiPos = (j + 24) % 24 + 20;      // 与 obb.jqmc 对应, "霜降"距首位"冬至"的距离为 20
                if(jieQiPos >= 24)
                    jieQiPos -= 24;

                jieqiList[counter, JiQiInfo_JieOrQi] = true;
                jieqiList[counter, JiQiInfo_Name] = obb.jqmc[jieQiPos];
                jieqiList[counter, JiQiInfo_YueJian] = obb.JieQiYueJian[jieQiPos];
                jieqiList[counter, JiQiInfo_JDTime] = v + LunarHelper.J2000;

                jieqiList[counter, JiQiInfo_HistoricalTime] = JD.setFromJD_str(qi + LunarHelper.J2000);
                jieqiList[counter, JiQiInfo_HistoricalJDTime] = qi + LunarHelper.J2000;
                jieqiList[counter, JiQiInfo_DifferentTime] = (LunarHelper.int2(v + 0.5) != qi ? true : false);

                jieqiList[counter, JiQiInfo_DayDifference] = (int)(LunarHelper.int2(v + 0.5) - qi);

                counter ++;
            }

            for(j = 0; j < SSQ.ZQ.Count; j++)    // △重要: 由于调用了 SSQ.calcJieQi 方法, 计算了 31 个节气(超出年周期)数据, 故应清零
                SSQ.ZQ[j] = 0;

            if (ob.y >= 0)
            {
                int ymd = ob.y * 10000 + ob.m * 100 + ob.d;     // 转换成为数值表示的日期: 如 20090422
                for (j = counter - 1; j >= 0; j--)    // 逆序查表(表中的交节日期数据是由小到大排列的)
                {
                    string jieqiTime = (string)jieqiList[j, JiQiInfo_Time];
                    int jieqiYear = int.Parse(jieqiTime.Substring(0, 5));
                    int jieqiMonth = int.Parse(jieqiTime.Substring(6, 2));
                    int jieqiDay = int.Parse(jieqiTime.Substring(9, 2));
                    if (jieqiYear * 10000 + jieqiMonth * 100 + jieqiDay <= ymd)    // 找到所属的节气
                    {
                        thisJie = j;
                        break;
                    }
                }
            }
            else
            {
                int ymd = ob.y * 10000 - (99 - ob.m) * 100 - (99 - ob.d);
                for (j = 0; j < counter; j++)    // 顺序查表(表中的交节日期数据是由小到大排列的, 计算为数值时也要严格递增)
                {
                    string jieqiTime = (string)jieqiList[j, JiQiInfo_Time];
                    int jieqiYear = int.Parse(jieqiTime.Substring(0, 5));
                    int jieqiMonth = int.Parse(jieqiTime.Substring(6, 2));
                    int jieqiDay = int.Parse(jieqiTime.Substring(9, 2));
                    int jieqiYmd = jieqiYear * 10000 - (99 - jieqiMonth) * 100 - (99 - jieqiDay);
                    if (jieqiYmd >= ymd)
                    {
                        if (jieqiYmd > ymd)
                            thisJie = j - 1;
                        else
                            thisJie = j;
                        break;
                    }
                }
            }

            if (thisJie > 0 && thisJie < counter)
            {
                jieqiInfoPos[ThisJieQiFlag] = thisJie;
                jieqiInfoPos[PrevJieQiFlag] = jieqiInfoPos[ThisJieQiFlag] - 1;
                jieqiInfoPos[NextJieQiFlag] = jieqiInfoPos[ThisJieQiFlag] + 1;

                for (j = 0; j < jieqiInfoPos.Length; j++)
                {
                    switch (j)
                    {
                        case PrevJieQiFlag:
                            jieqiInfo = ob.PreviousJieQi;
                            break;

                        case ThisJieQiFlag:
                            jieqiInfo = ob.ThisJieQi;
                            break;

                        case NextJieQiFlag:
                            jieqiInfo = ob.NextJieQi;
                            break;

                        default:
                            jieqiInfo = null;
                            break;
                    }

                    if (jieqiInfo != null)
                    {
                        jieqiInfo.JieOrQi = (bool)jieqiList[jieqiInfoPos[j], JiQiInfo_JieOrQi];
                        jieqiInfo.Name = (string)jieqiList[jieqiInfoPos[j], JiQiInfo_Name];
                        jieqiInfo.YueJian = (string)jieqiList[jieqiInfoPos[j], JiQiInfo_YueJian];
                        jieqiInfo.Time = (string)jieqiList[jieqiInfoPos[j], JiQiInfo_Time];
                        jieqiInfo.JDTime = (double)jieqiList[jieqiInfoPos[j], JiQiInfo_JDTime];

                        jieqiInfo.HistoricalTime = (string)jieqiList[jieqiInfoPos[j], JiQiInfo_HistoricalTime];
                        jieqiInfo.HistoricalJDTime = (double)jieqiList[jieqiInfoPos[j], JiQiInfo_HistoricalJDTime];
                        jieqiInfo.DifferentTime = (bool)jieqiList[jieqiInfoPos[j], JiQiInfo_DifferentTime];

                        jieqiInfo.DayDifference = (int)jieqiList[jieqiInfoPos[j], JiQiInfo_DayDifference];
                    }
                }

                return true;
            }

            return false;
        }
Пример #12
0
 /// <summary>
 /// 回历计算, 并保存信息到日对象中
 /// </summary>
 /// <param name="d0">2000.0起算儒略日,北京时12:00</param>
 /// <param name="r">日对象</param>
 public static void getHuiLi(double d0, OB r)
 {
     // 以下算法使用Excel测试得到,测试时主要关心年临界与月临界
     double z, y, m, d;
     d = d0 + 503105; z = LunarHelper.int2((d + 0.1) / 10631);   // 10631为一周期(30年)
     d -= z * 10631; y = LunarHelper.int2((d + 0.5) / 354.366);  // 加0.5的作用是保证闰年正确(一周中的闰年是第2,5,7,10,13,16,18,21,24,26,29年)
     d -= LunarHelper.int2(y * 354.366 + 0.5); m = LunarHelper.int2((d + 0.11) / 29.51);   // 分子加0.11,分每加0.01的作用是第354或355天的的月分保持为12月(m=11)
     d -= LunarHelper.int2(m * 29.51 + 0.5);
     r.Hyear = z * 30 + y + 1;
     r.Hmonth = m + 1;
     r.Hday = d + 1;
 }
Пример #13
0
        /// <summary>
        /// 计算某日节日的信息, 并保存信息到日对象中
        /// </summary>
        /// <param name="u">日对象</param>
        /// <param name="r">日对象</param>
        public static void getDayName(OB u, OB r)
        {
            string m0 = (u.m < 10 ? "0" : "") + u.m;
            string d0 = (u.d < 10 ? "0" : "") + u.d;
            int    i;
            string s, s2, type;

            if (u.week == 0 || u.week == 6)
            {
                r.Fjia = 1;   // 星期日或星期六放假
            }
            // 按公历日期查找
            for (i = 0; i < oba.sFtv[u.m - 1].Length; i++)    // C#: 注: 属性 sFtv 在初始化时已经包含了 12 个元素, 以对应 12 个月
            {
                // 公历节日或纪念日,遍历本月节日表
                s = oba.sFtv[u.m - 1][i];
                if (s.Length < 3 || s.Substring(0, 2) != d0)    // C#: 新增了第 1 个判断条件
                {
                    continue;
                }
                s    = s.Substring(2, s.Length - 2);
                type = s.Substring(0, 1);
                if (s.Length >= 6 && s.Substring(5, 1) == "-")
                {
                    // 有年限的节日
                    if (u.y < (int.Parse(s.Substring(1, 4))) || u.y > (int.Parse(s.Substring(6, 4))))
                    {
                        continue;
                    }
                    s = s.Substring(10, s.Length - 10);
                }
                else
                {
                    if (u.y < 1850)
                    {
                        continue;
                    }
                    s = s.Substring(1, s.Length - 1);
                }
                if (type == "#")
                {
                    r.A += s + " "; r.Fjia = 1;
                }                                                //放假的节日
                if (type == "I")
                {
                    r.B += s + " ";              //主要
                }
                if (type == ".")
                {
                    r.C += s + " ";              //其它
                }
            }

            // 按周规则查找
            double w = u.weeki;

            if (u.week >= u.week0)
            {
                w += 1;
            }
            double w2 = w;

            if (u.weeki == u.weekN - 1)
            {
                w2 = 5;
            }
            string w__  = m0 + w + u.week;   // d日在本月的第几个星期某
            string w2__ = m0 + w2 + u.week;

            for (i = 0; i < oba.wFtv.Length; i++)
            {
                s  = oba.wFtv[i];
                s2 = s.Substring(0, 4);
                if (s2 != w__ && s2 != w2__)
                {
                    continue;
                }
                type = s.Substring(4, 1);
                s    = s.Substring(5, s.Length - 5);
                if (type == "#")
                {
                    r.A += s + " "; r.Fjia = 1;
                }
                if (type == "I")
                {
                    r.B += s + " ";
                }
                if (type == ".")
                {
                    r.C += s + " ";
                }
            }
        }