Esempio n. 1
0
        /// <summary>
        /// 计算指定节气的时间
        /// </summary>
        /// <param name="year">公历年份</param>
        /// <param name="st">节气</param>
        /// <returns>返回指定节气的儒略日时间</returns>
        public static double CalcSolarTerms(int year, SolarTerm24Types st)
        {
            SolarTerm24 jq  = new SolarTerm24(st);
            int         jq1 = jq.Degree;

            // 节气月份
            int SolarTermsMonth = (int)(Math.Ceiling(((jq1 + 90.0) / 30.0)));

            SolarTermsMonth = SolarTermsMonth > 12 ? SolarTermsMonth - 12 : SolarTermsMonth;

            // 节令的发生日期基本都在每月 3 - 9 号间  update by Ukey 2017-01-01 从4-9提升到3-9,有年的立春在3号
            int LowerLimitSolarTermsDay = jq1 % 15 == 0 && jq1 % 30 != 0 ? 3 : 16;
            // 节气的发生日期基本都在每月 16 - 24 号间
            int UpperLimitSolarTermsDay = jq1 % 15 == 0 && jq1 % 30 != 0 ? 9 : 24;

            // 采用二分法逼近计算
            double dbLowerLinit = Julday(year, SolarTermsMonth, LowerLimitSolarTermsDay, 0, 0, 0);
            double dbUpperLinit = Julday(year, SolarTermsMonth, UpperLimitSolarTermsDay, 23, 59, 59);

            // 二分法分界点日期
            double dbDichotomyDivisionDayJD = 0;
            // 太阳黄经角度
            double dbLongitude = 0;

            // 对比二分法精度是否达到要求
            do
            {
                dbDichotomyDivisionDayJD = ((dbUpperLinit - dbLowerLinit) / 2.0) + dbLowerLinit;

                // 计算太阳黄经
                dbLongitude = GetSunLongitude(dbDichotomyDivisionDayJD);

                // 一次校正经度
                dbLongitude += CorrectionCalcSunLongitude(dbLongitude, GetSunLatitude(dbDichotomyDivisionDayJD), dbDichotomyDivisionDayJD);
                // 二次校正天体章动
                dbLongitude += GetNutationJamScalar(dbDichotomyDivisionDayJD) / 3600.0;
                // 三次校正太阳半径向量
                dbLongitude -= (20.4898 / GetSunRadiusVector(dbDichotomyDivisionDayJD)) / 3600.0;

                // 由于春分这天黄经为 0 度,比较特殊,因此专门判断(如不加以特殊对待则会导致计算范围覆盖整个 360 度角)
                dbLongitude = ((st == SolarTerm24Types.ChunFen) && (dbLongitude > 345.0)) ? -dbLongitude : dbLongitude;

                // 调整二分法上下限
                if (dbLongitude > (double)(jq1))
                {
                    dbUpperLinit = dbDichotomyDivisionDayJD;
                }
                else
                {
                    dbLowerLinit = dbDichotomyDivisionDayJD;
                }
            } while (Math.Abs(dbLongitude - (double)(jq1)) >= 0.00001);

            return(dbDichotomyDivisionDayJD);
        }
Esempio n. 2
0
        /// <summary>
        /// 获取本实例日期值是否正值某一节气日期。
        /// </summary>
        /// <returns>如果正好在某一节气上,返回节气信息,否则返回null</returns>
        public string GetSolarTermInfo(DateTime Value)
        {
            try
            {
                string      returnValue = "";
                int         y           = Value.Year;
                string      ds          = Value.ToString("yyyy-MM-dd");
                SolarTerm24 t           = new SolarTerm24(SolarTerm24Types.XiaoHan); //公历1月份第一个节气为小寒
                int         n           = Value.Month - 1;
                SolarTerm24 t1          = t.Inc(2 * n);                              //每个公历月上有2个节气 ,该月第一个节气
                DateTime    d1          = CalendarUtil.GetSolarTermDateTime(y, t1.ID);
                if (ds == d1.ToString("yyyy-MM-dd"))
                {
                    solarTermInfo = new HFDateSolarTermInfo(t1.ID, d1);
                }
                SolarTerm24 t2 = new SolarTerm24();

                SolarTerm24 t3 = new SolarTerm24(); //上个月的第二个节气
                DateTime    d3;                     //上个月第二个节气的时间
                t3 = t1.Prior();
                if (Value.Month == 1)               // edit by Ukey 2017-01-03 每年一月份计算上一个月第二个节气出错
                {
                    d3 = CalendarUtil.GetSolarTermDateTime(y - 1, t3.ID);
                }
                else
                {
                    d3 = CalendarUtil.GetSolarTermDateTime(y, t3.ID);
                }

                DateTime d2;    //本月第二个节气的日期
                t2 = t1.Next(); //本月第二个节气
                d2 = CalendarUtil.GetSolarTermDateTime(y, t2.ID);
                if (ds == d2.ToString("yyyy-MM-dd"))
                {
                    solarTermInfo = new HFDateSolarTermInfo(t2.ID, d2);
                }
                SolarTerm24 t4 = new SolarTerm24(); //下个月的第一个节气
                DateTime    d4;                     //下个月第一个节气的日期
                t4 = t2.Next();                     //下个月的第一个节气
                d4 = CalendarUtil.GetSolarTermDateTime(y, t4.ID);
                if (ds == d2.ToString("yyyy-MM-dd"))
                {
                    solarTermInfo = new HFDateSolarTermInfo(t2.ID, d2);
                }
                if (solarTermInfo != null)
                {
                    returnValue = solarTermInfo.Name;
                }
                else
                {
                    int daydiff = 0;
                    if (Value < d1)  //d1 该月的第一个节气时间 d2 该月的第二个节气时间 d3 上个月的第二个节气的时间  前七后八的显示方式
                    {
                        daydiff = (Value - d3).Days + 1;
                        if (daydiff <= 7)
                        {
                            returnValue = t3.Name + "后" + daydiff.ToString() + "天";
                        }
                        else
                        {
                            daydiff     = (d1 - Value).Days;
                            returnValue = t1.Name + "前" + daydiff.ToString() + "天";
                        }
                    }
                    else if (Value > d1 && Value < d2)
                    {
                        // returnValue = t1.Name + "第" + (Value.Date - d1.Date).Days.ToString() + "天";
                        daydiff = (Value - d1).Days + 1;
                        if (daydiff <= 7)
                        {
                            returnValue = t1.Name + "后" + daydiff.ToString() + "天";
                        }
                        else
                        {
                            daydiff     = (d2 - Value).Days;
                            returnValue = t2.Name + "前" + daydiff.ToString() + "天";
                        }
                    }
                    else if (Value > d2)
                    {
                        //  returnValue = t2.Name + "第" + (Value.Date - d2.Date).Days.ToString() + "天";

                        daydiff = (Value - d2).Days + 1;
                        if (daydiff <= 7)
                        {
                            returnValue = t2.Name + "后" + daydiff.ToString() + "天";
                        }
                        else
                        {
                            daydiff     = (d4 - Value).Days;
                            returnValue = t4.Name + "前" + daydiff.ToString() + "天";
                        }
                    }
                }
                solarTermInfo = null;
                return(returnValue);
            }
            catch (Exception ex)
            {
                return("小寒");
            }
        }