Example #1
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));
        }
Example #2
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;
        }
Example #3
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]));
        }
Example #4
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]);          //升起对应的时角
     }
 }
Example #5
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度
     }
 }
Example #6
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);
        }
Example #7
0
        /// <summary>
        /// 太阳到中升降时刻计算,传入jd是当地中午12点时间对应的2000年首起算的格林尼治时间UT
        /// </summary>
        /// <param name="jd"></param>
        /// <returns></returns>
        public static LunarInfoListT <double> St(double jd)
        {
            SZJ.dt = JD.deltatT2(jd);
            SZJ.E  = ZB.hcjj(jd / 36525);
            jd    -= LunarHelper.mod2(jd - SZJ.L / LunarHelper.pi2, 1); //查找最靠近当日中午的日上中天,mod2的第1参数为本地时角近似值

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

            r.z__ = r.s__ = r.j__ = r.c__ = r.h__ = jd;
            SZJ.Scoord(jd, 1, 1, r);       //太阳坐标
            r.s__ += (-r.H0 - r.H) / sv;   //升起
            r.j__ += (r.H0 - r.H) / sv;    //降落
            r.c__ += (-r.H1 - r.H) / sv;   //民用晨
            r.h__ += (r.H1 - r.H) / sv;    //民用昏
            r.z__ += (0 - r.H) / sv;       //中天
            SZJ.Scoord(r.s__, 1, 0, r); r.s__ += (-r.H0 - r.H) / sv;
            SZJ.Scoord(r.j__, 1, 0, r); r.j__ += (+r.H0 - r.H) / sv;
            SZJ.Scoord(r.c__, 0, 1, r); r.c__ += (-r.H1 - r.H) / sv;
            SZJ.Scoord(r.h__, 0, 1, r); r.h__ += (+r.H1 - r.H) / sv;
            SZJ.Scoord(r.z__, 0, 0, r); r.z__ += (0 - r.H) / sv;
            return(r);
        }
Example #8
0
 /// <summary>
 /// 返回月球坐标,n1,n2,n3为各坐标所取的项数
 /// </summary>
 /// <param name="t"></param>
 /// <param name="re"></param>
 /// <param name="n1"></param>
 /// <param name="n2"></param>
 /// <param name="n3"></param>
 public static void M_coord(double t, LunarInfoListT <double> re, double n1, double n2, double n3)    // C#: 新扩展出来的方法
 {
     re[0] = XL.Mnn(XL.ML, t, n1);
     re[1] = XL.Mnn(XL.MB, t, n2);
     re[2] = XL.Mnn(XL.MR, t, n3);
 }
Example #9
0
        /// <summary>
        /// 农历排月序计算,可定出农历,有效范围:两个冬至之间(冬至一 ≤ d < 冬至二)
        /// </summary>
        /// <param name="jd"></param>
        public static void calcY(double jd)
        {
            LunarInfoListT <double> A = SSQ.ZQ;

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

            // 该年的气
            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, "气");  // 补算二气,确保一年中所有月份的“气”全部被计算在内

            // 今年"首朔"的日月黄经差w
            w = SSQ.calc(A[0], "朔");    // 求较靠近冬至的朔日
            if (w > A[0])
            {
                w -= 29.53;
            }

            // 该年所有朔,包含14个月的始末
            for (i = 0; i < 15; i++)
            {
                B[i] = SSQ.calc(w + 29.5306 * i, "朔");
            }

            // 月大小
            SSQ.leap = 0;
            for (i = 0; i < 14; i++)
            {
                SSQ.dx[i] = SSQ.HS[i + 1] - SSQ.HS[i]; // 月大小
                SSQ.ym[i] = i.ToString();              // 月序初始化
            }



            // -721年至-104年的后九月及月建问题,与朔有关,与气无关
            double YY = LunarHelper.int2((SSQ.ZQ[0] + 10 + 180) / 365.2422) + 2000; // 确定年份

            if (YY >= -721 && YY <= -104)
            {
                double ly = 0, b0 = 0, k0 = 0, x0 = 0;    // ly为历元(本历首月的儒略数),x0月建,lName闰月名称,b0,k0为置闰拟合参数
                string lName = "";

                if (YY >= -721)
                {
                    ly = 1457698 - LunarHelper.J2000; k0 = 12.368422; b0 = 0.342; lName = "十三"; x0 = 2;
                }                                                                                                          // 春秋历,ly为-722.12.17
                if (YY >= -479)
                {
                    ly = 1546083 - LunarHelper.J2000; k0 = 12.368422; b0 = 0.500; lName = "十三"; x0 = 2;
                }                                                                                                          // 战国历,ly为-480.12.11
                if (YY >= -220)
                {
                    ly = 1640641 - LunarHelper.J2000; k0 = 12.369000; b0 = 0.866; lName = "后九"; x0 = 11;
                }                                                                                         // 秦汉历,ly为-221.10.31;

                double nY = LunarHelper.int2((SSQ.HS[0] - ly + 100) / 365.25);                            // 年积数
                double f1 = LunarHelper.int2(b0 + nY * k0), f2 = LunarHelper.int2(b0 + nY * k0 + k0), f3; // f1有本年首的月积数,f2为下一年首的月积数
                f1 = LunarHelper.int2(f1); f2 = LunarHelper.int2(f2);
                for (i = 0; i < 14; i++)
                {
                    f3 = LunarHelper.int2((SSQ.HS[i] - ly + 15) / 29.5306);    // 该月积数
                    if (f3 < f2)
                    {
                        f3 -= f1;
                    }
                    else
                    {
                        f3 -= f2;
                    }
                    if (f3 < 12)
                    {
                        SSQ.ym[i] = obb.ymc[(int)((f3 + x0) % 12)];
                    }
                    else
                    {
                        SSQ.ym[i] = lName;
                    }
                }
                return;
            }

            // 无中气置闰法确定闰月,(气朔结合法,数据源需有冬至开始的的气和朔)
            if (B[13] <= A[24])
            {
                // 第13月的月末没有超过冬至(不含冬至),说明今年含有13个月
                for (i = 1; B[i + 1] > A[2 * i] && i < 13; i++)
                {
                    ;                                             //在13个月中找第1个没有中气的月份
                }
                SSQ.leap = i;
                for (; i < 14; i++)
                {
                    SSQ.ym[i] = (int.Parse(SSQ.ym[i]) - 1).ToString();
                }
            }

            // 名称转换(月建别名)
            for (i = 0; i < 14; i++)
            {
                double Dm = SSQ.HS[i] + LunarHelper.J2000, v2 = int.Parse(SSQ.ym[i]); // Dm初一的儒略日,v2为月建序号
                string mc = obb.ymc[(int)(v2 % 12)];                                  // 月建对应的默认月名称:建子十一,建丑十二,建寅为正……
                if (Dm >= 1724360 && Dm <= 1729794)
                {
                    mc = obb.ymc[(int)((v2 + 1) % 12)];                                        //  8.01.15至 23.12.02 建子为十二,其它顺推
                }
                else if (Dm >= 1807724 && Dm <= 1808699)
                {
                    mc = obb.ymc[(int)((v2 + 1) % 12)];                                        // 237.04.12至239.12.13 建子为十二,其它顺推
                }
                else if (Dm >= 1999349 && Dm <= 1999467)
                {
                    mc = obb.ymc[(int)((v2 + 2) % 12)];                                        // 761.12.02至762.03.30 建子为正月,其它顺推
                }
                else if (Dm >= 1973067 && Dm <= 1977112)
                {
                    if (v2 % 12 == 0)
                    {
                        mc = "正";
                    }
                    if (v2 == 2)
                    {
                        mc = "一";
                    }
                }                                                                                                  // 689.12.18至701.01.14 建子为正月,建寅为一月,其它不变

                if (Dm == 1729794 || Dm == 1808699)
                {
                    mc = "拾贰";                                    // 239.12.13及23.12.02均为十二月,为避免两个连续十二月,此处改名
                }
                SSQ.ym[i] = mc;
            }
        }