Esempio n. 1
0
        /// <summary>
        /// 求空间两点连线与地球的交点(靠近点1的交点),返回在ZB.le_J,le_W,赤道坐标。R1,R2单位是千米
        /// </summary>
        /// <param name="J1"></param>
        /// <param name="W1"></param>
        /// <param name="R1"></param>
        /// <param name="J2"></param>
        /// <param name="W2"></param>
        /// <param name="R2"></param>
        public static void line_earth(double J1, double W1, double R1, double J2, double W2, double R2)
        {
            double x1 = R1 * Math.Cos(W1) * Math.Cos(J1), y1 = R1 * Math.Cos(W1) * Math.Sin(J1), z1 = R1 * Math.Sin(W1);
            double x2 = R2 * Math.Cos(W2) * Math.Cos(J2), y2 = R2 * Math.Cos(W2) * Math.Sin(J2), z2 = R2 * Math.Sin(W2);
            double dx = x2 - x1, dy = y2 - y1, dz = z2 - z1, f = 0.99664719, r = LunarHelper.cs_rEar; //直线参数及地球参数
            double x, y, z, lh = 0;

            if (Math.Abs(dx) < Math.Abs(dy)) //必要时仑换
            {
                lh = dx; dx = dy; dy = lh; lh = x1; x1 = y1; y1 = lh; lh = 1;
            }
            double a = dy / dx, b = y1 - a * x1, c = dz / dx / f, d = z1 / f - c * x1;
            double A = a * a + c * c + 1, B = a * b + c * d, C = b * b + d * d - r * r, D = B * B - A * C;

            if (D < 0)
            {
                ZB.le_J = ZB.le_W = 100; return;
            }                                               //返回100表示无解
            D = Math.Sqrt(D); if (x1 + B / A < 0)
            {
                D = -D;
            }
            x        = (-B + D) / A; y = a * x + b; z = (c * x + d) / f;
            ZB.le_R1 = Math.Sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1) + (z - z1) * (z - z1));
            if (lh != 0)
            {
                lh = x; x = y; y = lh;
            }
            ZB.le_W = Math.Atan(z / Math.Sqrt(x * x + y * y));
            ZB.le_J = LunarHelper.rad2mrad(Math.Atan2(y, x));
        }
Esempio n. 2
0
        private static xList <xList <string> > __sFtv = oba.getsFtvData();   // 国历节日,#表示放假日,I表示重要节日或纪念日

        #endregion



        #region 转换时新增的方法

        /// <summary>
        /// 从 Xml 文档对象加载 wFtv 数据
        /// </summary>
        /// <returns></returns>
        private static xList <string> getwFtvData()
        {
            xList <string> result = new xList <string>();

            //----------------------------------------------------------------------------------------
            // 加载 Xml 数据:  按周规则定义的节日(纪念日)
            // 注: 加载时自动去除各行 Xml 数据前、后端的所有空白字符, 但对数据内部的空白字符不作处理
            //----------------------------------------------------------------------------------------
            if (LunarHelper.SxwnlXmlData != null)
            {
                const string wFtvXPath = "SharpSxwnl/SxwnlData/Data[@Id = 'oba_wFtv']";
                XElement     foundNode;
                Regex        regexToTrim = new Regex(@"(^\s*)|(\s*$)"); // C#: 匹配任何空白字符

                // 读取并解开数据
                foundNode = LunarHelper.GetXmlNode("oba_wFtv");
                if (foundNode != null)
                {
                    string[] wftv = regexToTrim.Replace(foundNode.Value, "").Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                    for (int i = 0; i < wftv.Length; i++)
                    {
                        result.Add(regexToTrim.Replace(wftv[i], ""));
                    }
                }
            }

            return(result);
        }
Esempio n. 3
0
        private static double[] __Yn = new double[1];                                      //年计数

        #endregion



        #region 转换时新增加的方法

        /// <summary>
        /// 新增方法: 计算节气, 并返回计算的节气总数, 在调用本方法并读取 SSQ.ZQ 数据后, 应该清零 SSQ.ZQ
        /// </summary>
        /// <param name="jd"></param>
        /// <param name="calcMultiPeriod"></param>
        /// <returns></returns>
        public static int calcJieQi(double jd, bool calcMultiPeriod)
        {
            LunarInfoListT <double> A = SSQ.ZQ;

            double[] B = SSQ.HS;    // 中气表,日月合朔表(整日)
            int      i;
            double   W;

            if (!calcMultiPeriod)                                                   // 只计算某年的节气
            {
                W = LunarHelper.int2((jd - 355 + 183) / 365.2422) * 365.2422 + 355; // 355是2000.12冬至,得到较靠近jd的冬至估计值
                if (SSQ.calc(W, "气") > jd)
                {
                    W -= 365.2422;
                }
                for (i = 0; i < 25; i++)
                {
                    A[i] = SSQ.calc(W + 15.2184 * i, "气");                          // 25个节气时刻(北京时间),从冬至开始到下一个冬至以后
                }
                A.pe1 = SSQ.calc(W - 15.2, "气"); A.pe2 = SSQ.calc(W - 30.4, "气");   // 补算二气,确保一年中所有月份的“气”全部被计算在内
            }
            else                                                                    // 需计算从霜降至下 2 个大寒之后的节气, 用于计算指定日期的所属节气, 上一节气, 下一节气等信息
            {
                W = LunarHelper.int2((jd - 355 + 183) / 365.2422) * 365.2422 + 296; // 296是2000.10.23霜降(距200.1.1的天数),得到较靠近jd的霜降估计值
                if (SSQ.calc(W, "气") > jd)
                {
                    W -= 365.2422;
                }
                for (i = 0; i < 31; i++)
                {
                    A[i] = SSQ.calc(W + 15.2184 * i, "气");                          // 31个节气时刻(北京时间),从霜降至开始到下 2 个大寒以后
                }
            }
            return((!calcMultiPeriod ? 25 : 31));
        }
Esempio n. 4
0
        /// <summary>
        /// 将度分秒转换为弧度值(只作简单转化, 要求传递的格式严格遵守"度分秒"的格式, 如: 0°0'31.49"
        /// </summary>
        /// <param name="d"></param>
        /// <returns></returns>
        public static double str2rad(string d)
        {
            double result     = 0;
            string strSpliter = "°'\"";

            char[]   spliters = strSpliter.ToCharArray();
            string[] strD     = d.Split(spliters, StringSplitOptions.RemoveEmptyEntries);

            if (strD.Length > 0)
            {
                double a = 0, b = 0, c = 0;
                a = LunarHelper.VAL(strD[0]) / 180 * Math.PI;                     // 1°= 1/180*PI ≈ 0.017453292519943 弧度
                if (strD.Length > 1)
                {
                    b = LunarHelper.VAL(strD[1]) / 60 / 180 * Math.PI;            // 1' = (1/60)°≈ 0.000290888208666 弧度
                    if (strD.Length > 2)
                    {
                        c = LunarHelper.VAL(strD[2]) / 60 / 180 / 60 * Math.PI;   // 1" = (1/60)' ≈ 0.000004848136811 弧度
                    }
                }
                if (a > 0)
                {
                    result = a + b + c;
                }
                else
                {
                    result = a - b - c;
                }
            }
            return(result);
        }
Esempio n. 5
0
        /// <summary>
        /// 儒略日数转公历
        /// </summary>
        /// <param name="jd">儒略日</param>
        public static void setFromJD(double jd)
        {
            jd += 0.5;
            double A = LunarHelper.int2(jd), F = jd - A, D;  //取得日数的整数部份A及小数部分F

            if (A >= 2299161)
            {
                D  = LunarHelper.int2((A - 1867216.25) / 36524.25);
                A += 1 + D - LunarHelper.int2(D / 4);
            }
            A    += 1524;                                   //向前移4年零2个月
            JD.Y  = LunarHelper.int2((A - 122.1) / 365.25); //年
            D     = A - LunarHelper.int2(365.25 * JD.Y);    //去除整年日数后余下日数
            JD.M  = LunarHelper.int2(D / 30.6001);          //月数
            JD.D  = D - LunarHelper.int2(JD.M * 30.6001);   //去除整月日数后余下日数
            JD.Y -= 4716; JD.M--;
            if (JD.M > 12)
            {
                JD.M -= 12;
            }
            if (JD.M <= 2)
            {
                JD.Y++;
            }

            //日的小数转为时分秒
            F *= 24; JD.h = LunarHelper.int2(F); F -= JD.h;
            F *= 60; JD.m = LunarHelper.int2(F); F -= JD.m;
            F *= 60; JD.s = F;
        }
Esempio n. 6
0
        /// <summary>
        /// 时差计算(高精度)
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public static double shiCha(double t)
        {
            double t2 = t * t, t3 = t2 * t, t4 = t3 * t, t5 = t4 * t;
            double L = (1753469512 + 628331965331.8 * t + 5296.74 * t2 + 0.432 * t3 - 0.1124 * t4 - 0.00009 * t5 + 630 * Math.Cos(6 + 0.3 * t)) / 1000000000 + Math.PI - 20.5 / LunarHelper.rad;

            double E, dE, dL;

            double[] z = new double[2];                                     // C#: 待定(?)
            dL = -17.2 * Math.Sin(2.1824 - 33.75705 * t) / LunarHelper.rad; //黄经章
            dE = 9.2 * Math.Cos(2.1824 - 33.75705 * t) / LunarHelper.rad;   //交角章
            E  = ZB.hcjj(t) + dE;                                           //真黄赤交角

            //地球坐标
            z[0] = XL.E_Lon(t, 50) + Math.PI + ZB.gxc_sunLon(t) + dL;
            z[1] = -(2796 * Math.Cos(3.1987 + 8433.46616 * t) + 1016 * Math.Cos(5.4225 + 550.75532 * t) + 804 * Math.Cos(3.88 + 522.3694 * t)) / 1000000000;

            ZB.llrConv(z, E); //z太阳地心赤道坐标
            z[0] -= dL * Math.Cos(E);

            L = LunarHelper.rad2mrad(L - z[0]);
            if (L > Math.PI)
            {
                L -= LunarHelper.pi2;
            }
            return(L / LunarHelper.pi2); //单位是周(天)
        }
Esempio n. 7
0
        /// <summary>
        /// 计算本月所有日期的日十二建信息
        /// </summary>
        private void CalcRiJianThisMonth()
        {
            OB     lunOb;
            string yuejian = String.Empty;

            //OB ob = new OB();

            for (int i = 0; i < this.dn; i++)    // 遍历月
            {
                lunOb = this.lun[i];

                //if (i == 0 || lunOb.jqmc.Trim().Length > 0 || lunOb.Ljq.Trim().Length > 0)    // 每月第 1 日, 或遇到了交节气日, 则计算该日的所属节气等
                //{
                //    ob.y = lunOb.y;
                //    ob.m = lunOb.m;
                //    ob.d = lunOb.d;
                //    this.CalcJieQiInfo(ob, CalcJieQiType.CalcJie);
                //}
                //yuejian = ob.ThisJieQi.YueJian;
                //if (ob.ThisJieQi.DifferentTime)
                //    yuejian = LunarHelper.SUBSTRING(lunOb.Lmonth2, 1, 1);     // 调整为实历

                // 可直接使用该属性的月建而无需再次计算节气, 但上述被注释的代码也可用(主要为了测试 CalcJieQiInfo 方法, 暂保留)
                yuejian = LunarHelper.SUBSTRING(lunOb.Lmonth2, 1, 1);

                lunOb.Ri12Jian = this.GetRi12Jian(yuejian, LunarHelper.SUBSTRING(lunOb.Lday2, 1, 1));    // 计算日十二建
            }
        }
Esempio n. 8
0
        /// <summary>
        /// 传入普通纪年或天文纪年,传回天文纪年
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="c">普通纪年或天文纪年, 泛型, 支持数值或字符串</param>
        /// <returns></returns>
        public static int year2Ayear <T>(T c)
        {
            int    y;
            Regex  regexToReplace = new Regex(@"[^0-9Bb\*-]");                // C#: 匹配字符: 数字0-9, B, b, *, -
            string strC           = regexToReplace.Replace(c.ToString(), ""); // C#: 去除无效字符

            string q = strC.Substring(0, 1);

            if (q == "B" || q == "b" || q == "*")     //通用纪年法(公元前)
            {
                y = 1 - LunarHelper.VAL(strC.Substring(1), 1);
                if (y > 0)
                {
                    //MessageBox.Show("通用纪法的公元前纪法从 B.C.1 年开始,并且没有公元 0 年!",
                    //                "信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return(-10000);
                }
            }
            else
            {
                y = LunarHelper.VAL(strC, 1);
            }

            if (y < -4712)
            {
                //MessageBox.Show("不得小于 B.C.4713 年!", "信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return(-10000);
            }
            if (y > 9999)
            {
                //MessageBox.Show("超过9999年的农历计算很不准。", "信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }

            return(y);
        }
Esempio n. 9
0
        /// <summary>
        /// 构造函数, 完成纪年表数据的加载
        /// </summary>
        public JnbArrayList()
        {
            //----------------------------------------------------------------------------------------
            // 加载 Xml 数据:  历史纪年表
            // 注: 加载时自动去除历史纪年表 Xml 数据中所有的空白字符
            //----------------------------------------------------------------------------------------
            if (LunarHelper.SxwnlXmlData != null)
            {
                // const string JnbXPath = "SharpSxwnl/SxwnlData/Data[@Id = 'obb_JNB']";

                XElement foundNode;
                Regex    regexToTrim = new Regex(@"\s*"); // C#: 匹配任何空白字符, 用于去除所有空白字符
                int      i;

                // 读取并解开历史纪年表
                // foundNode = LunarHelper.SxwnlXmlData.SelectSingleNode(JnbXPath);
                foundNode = LunarHelper.GetXmlNode("obb_JNB");
                if (foundNode != null)
                {
                    string[] JNB = regexToTrim.Replace(foundNode.Value, "").Split(',');

                    this.AddRange(JNB);
                    for (i = 0; i < JNB.Length; i += 7)
                    {
                        this[i]     = int.Parse((string)(this[i]));
                        this[i + 1] = int.Parse((string)(this[i + 1]));
                        this[i + 2] = int.Parse((string)(this[i + 2]));
                    }
                }
            }
        }
Esempio n. 10
0
        /// <summary>
        /// 把太阳月亮信息形成纯文本字符串
        /// </summary>
        /// <param name="fs">是否显示ΔT, 黄经章等信息</param>
        /// <returns></returns>
        public string toText(double fs)
        {
            StringBuilder sb = new StringBuilder();

            sb.Append("平太阳 " + JD.timeStr(this.pty) + " 真太阳 " + JD.timeStr(this.zty) + "\r\n");
            sb.Append("时差 " + LunarHelper.m2fm(this.sc * 86400, 2, 1) + " 月亮被照亮 " + (this.mIll * 100).ToString("F2") + "% ");
            sb.Append("\r\n");

            sb.Append("\r\n表一       月亮            太阳\r\n");
            sb.Append("视黄经 " + LunarHelper.rad2str(this.mHJ, 0) + "  " + LunarHelper.rad2str(this.sHJ, 0) + "\r\n");
            sb.Append("视黄纬 " + LunarHelper.rad2str(this.mHW, 0) + "  " + LunarHelper.rad2str(this.sHW, 0) + "\r\n");
            sb.Append("视赤经 " + LunarHelper.rad2str(this.mCJ, 1) + "  " + LunarHelper.rad2str(this.sCJ, 1) + "\r\n");
            sb.Append("视赤纬 " + LunarHelper.rad2str(this.mCW, 0) + "  " + LunarHelper.rad2str(this.sCW, 0) + "\r\n");
            sb.Append("距离     " + this.mR.ToString("F0") + "千米          " + this.sR.ToString("F6") + "AU" + "\r\n");

            sb.Append("\r\n表二       月亮            太阳\r\n");
            sb.Append("方位角 " + LunarHelper.rad2str(this.mPJ, 0) + "  " + LunarHelper.rad2str(this.sPJ, 0) + "\r\n");
            sb.Append("高度角 " + LunarHelper.rad2str(this.mPW, 0) + "  " + LunarHelper.rad2str(this.sPW, 0) + "\r\n");
            sb.Append("时角   " + LunarHelper.rad2str(this.mShiJ, 0) + "  " + LunarHelper.rad2str(this.sShiJ, 0) + "\r\n");
            sb.Append("视半径(观测点) " + LunarHelper.m2fm(this.mRad, 2, 0) + "     " + LunarHelper.m2fm(this.sRad, 2, 0) + "\r\n");

            if (fs != 0)
            {
                sb.Append("\r\n力学时 " + JD.setFromJD_str(this.T + LunarHelper.J2000));
                sb.Append(" ΔT=" + (this.dt * 86400).ToString("F1") + "秒\r\n");
                sb.Append("黄经章 " + (this.dL / LunarHelper.pi2 * 360 * 3600).ToString("F2") + "\" ");
                sb.Append("交角章 " + (this.dE / LunarHelper.pi2 * 360 * 3600).ToString("F2") + "\" ");
                sb.Append("\r\nε=" + LunarHelper.trim(LunarHelper.rad2str(this.E, 0)));
            }
            return(sb.ToString());
        }
Esempio n. 11
0
        /// <summary>
        /// 从 Xml 对象中读取农历节日的定义
        /// </summary>
        /// <returns></returns>
        private static xList <OB> getLunarFeasts()
        {
            const string xPath  = "SharpSxwnl/SxwnlData/Data[@Id = 'obb_getDayName']";
            xList <OB>   result = new xList <OB>();

            if (LunarHelper.SxwnlXmlData != null)
            {
                // XmlNodeList foundNodeList = LunarHelper.SxwnlXmlData.SelectNodes(xPath);
                XElement node = LunarHelper.GetXmlNode("obb_getDayName");
                if (node != null)
                {
                    foreach (XElement child in node.Elements())
                    {
                        result.Add(new OB());    // 添加日对象来记录节点信息
                        result[result.Count - 1].Lmc  = child.Attribute("Day").Value;
                        result[result.Count - 1].A    = child.Attribute("A").Value;
                        result[result.Count - 1].B    = child.Attribute("B").Value;
                        result[result.Count - 1].C    = child.Attribute("C").Value;
                        result[result.Count - 1].Fjia = LunarHelper.VAL(child.Attribute("Fjia").Value) == 0 ? 0 : 1;
                    }
                }
            }

            return(result);
        }
Esempio n. 12
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;
            }
        }
Esempio n. 13
0
        /// <summary>
        /// 传入天文纪年,传回显示用的常规纪年
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="y">天文纪年, 泛型, 支持数值或字符串</param>
        /// <returns></returns>
        public static string Ayear2year <T>(T y)
        {
            int result = LunarHelper.VAL(y.ToString(), 1);

            if (result <= 0)
            {
                return("B" + (-result + 1));
            }
            return(result.ToString());
        }
Esempio n. 14
0
        /// <summary>
        /// 多天升中降计算,jd是当地起始儒略日(中午时刻),sq是时区
        /// </summary>
        /// <param name="jd"></param>
        /// <param name="n"></param>
        /// <param name="Jdl"></param>
        /// <param name="Wdl"></param>
        /// <param name="sq"></param>
        public static void calcRTS(double jd, double n, double Jdl, double Wdl, double sq)
        {
            int    i;
            double c;
            LunarInfoListT <double> r;     // C#: 不需要实例化, 因此注释语句的后半部分:  = new LunarInfoListT<double>(3, 0d);

            // C#: 由于将 rts 设置为自动实现的公共属性, 故添加了以下代码段来初始化
            if (SZJ.rts == null)
            {
                SZJ.rts = new LunarInfoListT <LunarInfoListT <double> >();
            }

            if (SZJ.rts.Count == 0)
            {
                for (i = 0; i < 31; i++)
                {
                    SZJ.rts.Add(new LunarInfoListT <double>());
                    // SZJ.rts[i] = new LunarInfoListT();
                }
            }
            SZJ.L = Jdl; SZJ.fa = Wdl; sq /= 24; //设置站点参数
            for (i = 0; i < n; i++)
            {
                r = SZJ.rts[i]; r.Ms = r.Mz = r.Mj = "";
            }
            for (i = -1; i <= n; i++)
            {
                if (i >= 0 && i < n)
                {
                    //太阳
                    r = SZJ.St(jd + i + sq);
                    ((SZJ.rts[i])).s  = JD.timeStr(r.s__ - sq);          //升
                    ((SZJ.rts[i])).z  = JD.timeStr(r.z__ - sq);          //中
                    ((SZJ.rts[i])).j  = JD.timeStr(r.j__ - sq);          //降
                    ((SZJ.rts[i])).c  = JD.timeStr(r.c__ - sq);          //晨
                    ((SZJ.rts[i])).h  = JD.timeStr(r.h__ - sq);          //昏
                    ((SZJ.rts[i])).ch = JD.timeStr(r.h__ - r.c__ - 0.5); //光照时间,timeStr()内部+0.5,所以这里补上-0.5
                    ((SZJ.rts[i])).sj = JD.timeStr(r.j__ - r.s__ - 0.5); //昼长
                }
                r = SZJ.Mt(jd + i + sq);                                 //月亮
                c = LunarHelper.int2(r.s__ - sq + 0.5) - jd; if (c >= 0 && c < n)
                {
                    (SZJ.rts[(int)c]).Ms = JD.timeStr(r.s__ - sq);
                }
                c = LunarHelper.int2(r.z__ - sq + 0.5) - jd; if (c >= 0 && c < n)
                {
                    (SZJ.rts[(int)c]).Mz = JD.timeStr(r.z__ - sq);
                }
                c = LunarHelper.int2(r.j__ - sq + 0.5) - jd; if (c >= 0 && c < n)
                {
                    (SZJ.rts[(int)c]).Mj = JD.timeStr(r.j__ - sq);
                }
            }
            SZJ.rts.dn = n;
        }
Esempio n. 15
0
        /// <summary>
        /// 求角度差(未测试)
        /// </summary>
        /// <param name="J1"></param>
        /// <param name="W1"></param>
        /// <param name="J2"></param>
        /// <param name="W2"></param>
        /// <returns></returns>
        public static double j1_j2(double J1, double W1, double J2, double W2)
        {
            double dJ = LunarHelper.rad2rrad(J1 - J2), dW = W1 - W2;

            if (Math.Abs(dJ) < 1 / 1000 && Math.Abs(dW) < 1 / 1000)
            {
                dJ *= Math.Cos((W1 + W2) / 2);
                return(Math.Sqrt(dJ * dJ + dW * dW));
            }
            return(Math.Acos(Math.Sin(W1) * Math.Sin(W2) + Math.Cos(W1) * Math.Cos(W2) * Math.Cos(dJ)));
        }
Esempio n. 16
0
        /// <summary>
        /// 球面坐标旋转
        /// </summary>
        /// <param name="JW"></param>
        /// <param name="E"></param>
        public static void llrConv(double[] JW, double E)
        {
            //黄道赤道坐标变换,赤到黄E取负
            double sinE = Math.Sin(E), cosE = Math.Cos(E);
            double sinJ = Math.Sin(JW[0]), cosJ = Math.Cos(JW[0]);
            double sinW = Math.Sin(JW[1]), cosW = Math.Cos(JW[1]), tanW = Math.Tan(JW[1]);

            JW[0] = Math.Atan2(sinJ * cosE - tanW * sinE, cosJ);
            JW[1] = Math.Asin(cosE * sinW + sinE * cosW * sinJ);
            JW[0] = LunarHelper.rad2mrad(JW[0]);
        }
Esempio n. 17
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;
        }
Esempio n. 18
0
        /// <summary>
        /// 球面坐标旋转
        /// </summary>
        /// <param name="JW"></param>
        /// <param name="E"></param>
        public static void llrConv(LunarInfoListT <double> JW, double E)    // C#: 新扩展出来的方法
        {
            //黄道赤道坐标变换,赤到黄E取负
            double sinE = Math.Sin(E), cosE = Math.Cos(E);
            double sinJ = Math.Sin((JW[0])), cosJ = Math.Cos((JW[0]));
            double sinW = Math.Sin((JW[1]));
            double cosW = Math.Cos((JW[1]));
            double tanW = Math.Tan((JW[1]));

            JW[0] = Math.Atan2(sinJ * cosE - tanW * sinE, cosJ);
            JW[1] = Math.Asin(cosE * sinW + sinE * cosW * sinJ);
            JW[0] = LunarHelper.rad2mrad((JW[0]));
        }
Esempio n. 19
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");
        }
Esempio n. 20
0
 /// <summary>
 /// 章动同时影响恒星时和天体坐标,所以不计算章动。返回时角及赤经纬
 /// </summary>
 /// <param name="jd"></param>
 /// <param name="H0"></param>
 /// <param name="z"></param>
 public static void Mcoord(double jd, double H0, LunarInfoListT <double> z)
 {
     XL.M_coord((jd + SZJ.dt) / 36525, z, 30, 20, 8); //低精度月亮赤经纬
     ZB.llrConv(z, SZJ.E);                            //转为赤道坐标
     z.H = LunarHelper.rad2mrad(ZB.gst(jd, SZJ.dt) - SZJ.L - z[0]);
     if (z.H > Math.PI)
     {
         z.H -= LunarHelper.pi2;                //得到此刻天体时角
     }
     if (H0 != 0)
     {
         z.H0 = SZJ.getH(0.7275 * LunarHelper.cs_rEar / z[2] - 34 * 60 / LunarHelper.rad, z[1]);          //升起对应的时角
     }
 }
Esempio n. 21
0
 /// <summary>
 /// 章动同时影响恒星时和天体坐标,所以不计算章动。返回时角及赤经纬
 /// </summary>
 /// <param name="jd"></param>
 /// <param name="H0"></param>
 /// <param name="H1"></param>
 /// <param name="z"></param>
 public static void Scoord(double jd, double H0, double H1, LunarInfoListT <double> z)
 {
     z[0] = XL.E_Lon((jd + SZJ.dt) / 36525, 5) + Math.PI - 20.5 / LunarHelper.rad; //太阳坐标(修正了光行差)
     z[1] = 0d; z[2] = 1d;                                                         // C#: 添加 d, 强制为 double 类型, 否则在把该元素显式转换为 double 时会出错
     ZB.llrConv(z, SZJ.E);                                                         // 转为赤道坐标
     z.H = LunarHelper.rad2rrad(ZB.gst(jd, SZJ.dt) - SZJ.L - z[0]);                //得到此刻天体时角
     if (H0 != 0)
     {
         z.H0 = SZJ.getH(-50 * 60 / LunarHelper.rad, z[1]);           //地平以下50分
     }
     if (H1 != 0)
     {
         z.H1 = SZJ.getH(-Math.PI / 30, z[1]);           // 地平以下6度
     }
 }
Esempio n. 22
0
        /// <summary>
        /// 时差计算(低精度),误差约在1秒以内
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public static double shiCha2(double t)
        {
            double L = (1753469512 + 628331965331.8 * t + 5296.74 * t * t) / 1000000000 + Math.PI;

            double[] z = new double[2];    // C#: 待定(?)
            double   E = (84381.4088 - 46.836051 * t) / LunarHelper.rad;

            z[0] = XL.E_Lon(t, 5) + Math.PI; z[1] = 0; // 地球坐标
            ZB.llrConv(z, E);                          // z太阳地心赤道坐标
            L = LunarHelper.rad2mrad(L - z[0]);
            if (L > Math.PI)
            {
                L -= LunarHelper.pi2;
            }
            return(L / LunarHelper.pi2);     // 单位是周(天)
        }
Esempio n. 23
0
        /// <summary>
        /// 计算ML0或ML1或ML2
        /// </summary>
        /// <param name="ob"></param>
        /// <param name="t"></param>
        /// <param name="n"></param>
        /// <returns></returns>
        public static double Mnn(double[][] ob, double t, double n)
        {
            int i, j;

            double[] F;
            double   N, v = 0, tn = 1, c;
            double   t2 = t * t, t3 = t2 * t, t4 = t3 * t, t5 = t4 * t, tx = t - 10;

            if (ob == XL.ML)
            {
                v += (3.81034409 + 8399.684730072 * t - 3.319e-05 * t2 + 3.11e-08 * t3 - 2.033e-10 * t4) * LunarHelper.rad; //月球平黄经(弧度)
                v += 5028.792262 * t + 1.1124406 * t2 + 0.00007699 * t3 - 0.000023479 * t4 - 0.0000000178 * t5;             //岁差(角秒)
                if (tx > 0)
                {
                    v += -0.866 + 1.43 * tx + 0.054 * tx * tx;            // 对公元3000年至公元5000年的拟合,最大误差小于10角秒
                }
            }
            //t2 /= 1e4; t3 /= 1e8; t4 /= 1e8;    // C#: 此处的计算可能会导致数据精度过低, 故注释, 在下面引用的地方进行修改
            n *= 6; if (n < 0)
            {
                n = ob[0].Length;
            }
            for (i = 0; i < ob.Length; i++)  // C#: 注释循环变量中步长计算的后半语句:   , tn *= t)
            {
                F = ob[i];
                N = LunarHelper.int2(n * F.Length / ob[0].Length + 0.5); if (i != 0)
                {
                    N += 6;
                }
                if (N >= F.Length)
                {
                    N = F.Length;
                }
                for (j = 0, c = 0; j < N; j += 6)
                {
                    // c += F[j] * Math.Cos(F[j + 1] + t * F[j + 2] + t2 * F[j + 3] + t3 * F[j + 4] + t4 * F[j + 5]);  // C#: 原语句, 因可能导致数据精度过低, 故修改如下
                    c += F[j] * Math.Cos(F[j + 1] + t * F[j + 2] + t2 * F[j + 3] / 1e4 + t3 * F[j + 4] / 1e8 + t4 * F[j + 5] / 1e8);  // C#: 新语句
                }
                // v += c * tn;     // C#: 注释此句并改写如下
                v += c * tn * Math.Pow(t, i);
            }
            if (ob != XL.MR)
            {
                v /= LunarHelper.rad;
            }
            return(v);
        }
Esempio n. 24
0
        /// <summary>
        /// 初始化数据
        /// </summary>
        private static int InitJWdata()
        {
            JWdata.DaylightInfo  = String.Empty;
            JWdata.SQDescription = String.Empty;

            //----------------------------------------------------------------------------------------
            // 加载 Xml 数据:  各地经纬度表, 时区表
            // 注: 加载时自动去除 Xml 各行数据前、后端的所有空白字符, 但对数据内部的空白字符不作处理
            //----------------------------------------------------------------------------------------
            if (LunarHelper.SxwnlXmlData != null)
            {
                const string JWvXPath = "SharpSxwnl/SxwnlData/Data[@Id = 'JWdata_JWv']";
                const string SQvXPath = "SharpSxwnl/SxwnlData/Data[@Id = 'JWdata_SQv']";

                XElement foundNode;
                Regex    regexToTrim = new Regex(@"(^\s*)|(\s*$)"); // C#: 匹配任何前后端的空白字符
                char[]   lineFlags   = new char[] { '\r', '\n' };


                // 读取并解开各地经纬度表
                foundNode = LunarHelper.GetXmlNode("JWdata_JWv");
                if (foundNode != null)
                {
                    string[] strJWv = regexToTrim.Replace(foundNode.Value, "").Split(lineFlags, StringSplitOptions.RemoveEmptyEntries);
                    for (int i = 0; i < strJWv.Length; i++)
                    {
                        JWdata.JWv.Add(new xList <string>());
                        JWdata.JWv[i].AddRange(regexToTrim.Replace(strJWv[i], "").Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries));  //解开清单
                    }
                }


                // 读取并解开各时区表
                foundNode = LunarHelper.GetXmlNode("JWdata_SQv");
                if (foundNode != null)
                {
                    string[] strSQv = regexToTrim.Replace(foundNode.Value, "").Split(lineFlags, StringSplitOptions.RemoveEmptyEntries);
                    for (int i = 0; i < strSQv.Length; i++)
                    {
                        JWdata.SQv.Add(new xList <string>());
                        JWdata.SQv[i].AddRange(regexToTrim.Replace(strSQv[i], "").Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries));  //解开各地时区清单
                    }
                }
            }

            return(1);
        }
Esempio n. 25
0
        /// <summary>
        /// 月亮到中升降时刻计算,传入jd含义与St()函数相同
        /// </summary>
        /// <param name="jd"></param>
        /// <returns></returns>
        public static LunarInfoListT <double> Mt(double jd)
        {
            SZJ.dt = JD.deltatT2(jd);
            SZJ.E  = ZB.hcjj(jd / 36525);
            jd    -= LunarHelper.mod2(0.1726222 + 0.966136808032357 * jd - 0.0366 * SZJ.dt - SZJ.L / LunarHelper.pi2, 1); //查找最靠近当日中午的月上中天,mod2的第1参数为本地时角近似值

            LunarInfoListT <double> r = new LunarInfoListT <double>(3, 0d);
            double sv = LunarHelper.pi2 * 0.966;

            r.z__ = r.s__ = r.j__ = r.c__ = r.h__ = jd;
            SZJ.Mcoord(jd, 1, r); //月亮坐标
            r.s__ += (-r.H0 - r.H) / sv;
            r.j__ += (r.H0 - r.H) / sv;
            r.z__ += (0 - r.H) / sv;
            SZJ.Mcoord(r.s__, 1, r); r.s__ += (-r.H0 - r.H) / sv;
            SZJ.Mcoord(r.j__, 1, r); r.j__ += (+r.H0 - r.H) / sv;
            SZJ.Mcoord(r.z__, 0, r); r.z__ += (0 - r.H) / sv;
            return(r);
        }
Esempio n. 26
0
        /// <summary>
        /// 秒转为分秒
        /// </summary>
        /// <param name="v">要转换的秒</param>
        /// <param name="fx">小数点位数</param>
        /// <param name="fs">为 1 转为"分秒"格式, 否则转为"角分秒"格式</param>
        /// <returns></returns>
        public static string m2fm(double v, int fx, int fs)
        {
            string gn = "";

            if (v < 0)
            {
                v = -v; gn = "-";
            }
            double f = LunarHelper.int2(v / 60), m = v - f * 60;

            if (fs != 0)
            {
                return(gn + f + "分" + m.ToString("F" + fx) + "秒");
            }
            else
            {
                return(gn + f + "'" + m.ToString("F" + fx) + "\"");
            }
        }
Esempio n. 27
0
        /// <summary>
        /// 公历转儒略日
        /// </summary>
        /// <param name="y">年</param>
        /// <param name="m">月</param>
        /// <param name="d">日</param>
        /// <returns></returns>
        public static double JD__(double y, double m, double d)     // C#: 为了避免与类名相同而冲突(被视为构造函数), 按转换规范 1 为方法名添加下划线
        {
            double n = 0, G = 0;

            if (y * 372 + m * 31 + LunarHelper.int2(d) >= 588829)
            {
                G = 1;   //判断是否为格里高利历日1582*372+10*31+15
            }
            if (m <= 2)
            {
                m += 12; y--;
            }
            if (G != 0)
            {
                n = LunarHelper.int2(y / 100);
                n = 2 - n + LunarHelper.int2(n / 4);
            }    //加百年闰
            return(LunarHelper.int2(365.25 * (y + 4716) + 0.01) + LunarHelper.int2(30.6001 * (m + 1)) + d + n - 1524.5);
        }
Esempio n. 28
0
        /// <summary>
        /// 时间串转为小时
        /// </summary>
        /// <param name="s">时间串</param>
        /// <returns></returns>
        public static double timeStr2hour(string s)
        {
            Regex regexToReplace = new Regex(@"[^0-9:]");    // C#: 匹配字符: 数字0-9, :
            int   a, b, c;

            string[] timeStr = regexToReplace.Replace(s, "").Split(':'); // C#: 去除无效字符后, 按 : 分隔字符串
            for (int i = 0; i < timeStr.Length; i++)                     // C#: 即使参数 s 为空串, 也会产生一个数组元素
            {
                if (timeStr[i].Length == 0)                              // C#: 把空串设置为 "0"
                {
                    timeStr[i] = "0";
                }
            }
            switch (timeStr.Length)
            {
            case 1:
            {
                // C#: 为避免 Substring 方法超出范围取子串引发异常, 改用本类中的静态方法 SUBSTRING
                a = LunarHelper.VAL(LunarHelper.SUBSTRING(timeStr[0], 0, 2), 1);
                b = LunarHelper.VAL(LunarHelper.SUBSTRING(timeStr[0], 2, 2), 1);
                c = LunarHelper.VAL(LunarHelper.SUBSTRING(timeStr[0], 4, 2), 1);
                break;
            }

            case 2:
            {
                a = LunarHelper.VAL(timeStr[0], 1);
                b = LunarHelper.VAL(timeStr[1], 1);
                c = 0;
                break;
            }

            default:
            {
                a = LunarHelper.VAL(timeStr[0], 1);
                b = LunarHelper.VAL(timeStr[1], 1);
                c = LunarHelper.VAL(timeStr[2], 1);
                break;
            }
            }
            return(a + b / 60d + c / 3600d);
        }
Esempio n. 29
0
        /// <summary>
        /// 提取jd中的时间(去除日期)
        /// </summary>
        /// <param name="jd"></param>
        /// <returns></returns>
        public static string timeStr(double jd)
        {
            double h, m, s;

            jd += 0.5; jd = (jd - LunarHelper.int2(jd));
            jd *= 24; h = LunarHelper.int2(jd); jd -= h;
            jd *= 60; m = LunarHelper.int2(jd); jd -= m;
            jd *= 60; s = LunarHelper.int2(jd + 0.5);
            if (s >= 60)
            {
                s -= 60; m++;
            }
            if (m >= 60)
            {
                m -= 60; h++;
            }
            string hStr = "0" + h, mStr = "0" + m, sStr = "0" + s;

            return(hStr.Substring(hStr.Length - 2, 2) + ':' + mStr.Substring(mStr.Length - 2, 2) + ':' + sStr.Substring(sStr.Length - 2, 2));
        }
Esempio n. 30
0
        /// <summary>
        /// 从 Xml 对象中读取农历节日的定义
        /// </summary>
        /// <returns></returns>
        private static xList <string> getJieQiFeasts()
        {
            const string   xPath  = "SharpSxwnl/SxwnlData/Data[@Id = 'obb_JieqiFjia']";
            xList <string> result = new xList <string>();

            if (LunarHelper.SxwnlXmlData != null)
            {
                //XmlNode foundNode;
                Regex regexToTrim = new Regex(@"\s*");    // C#: 匹配任何空白字符, 用于去除所有空白字符

                // 读取并解开历史纪年表
                XElement foundNode = LunarHelper.GetXmlNode("obb_JieqiFjia");
                if (foundNode != null)
                {
                    string[] jieqiFeasts = regexToTrim.Replace(foundNode.Value, "").Split(',');
                    result.AddRange(jieqiFeasts);
                }
            }

            return(result);
        }