/// <summary> /// 计算指定节气的时间 /// </summary> /// <param name="year">公历年</param> /// <param name="st">节气</param> /// <returns>返回本地公历日期/时间,精确到秒</returns> public static DateTime GetSolarTermDateTime(int year, SolarTerm24Types st) { double jd = CalcSolarTerms(year, st); int y, m, d, min, h, s; CalGD(jd, out y, out m, out d, out h, out min, out s); DateTime gd = new DateTime(y, m, d, h, min, s, DateTimeKind.Utc); return(gd.ToLocalTime()); }
/// <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); }
/// <summary> /// /// </summary> /// <param name="jq"></param> /// <param name="n"></param> /// <returns></returns> private SolarTerm24Types Inc(SolarTerm24Types jq, int n) { int j = n % 24; if (j == 0) { return(jq); } int k = (int)jq + j; if (k > 23) { k -= 24; } else if (k < 0) { k += 24; } return((SolarTerm24Types)k); }
/// <summary> /// 构造函数 /// </summary> /// <param name="jq">节气</param> /// <param name="rq">日期/时间</param> public HFDateSolarTermInfo(SolarTerm24Types jq, DateTime rq) : base(jq) { date = rq; }
/// <summary> /// 将当前实例加上n后的实例值,n可以为负数 /// </summary> /// <param name="n">增加的数值</param> /// <returns></returns> public SolarTerm24 Inc(int n) { SolarTerm24Types jq = Inc(ID, n); return(new SolarTerm24(jq)); }
/// <summary> /// 构造函数 /// </summary> /// <param name="jq">指定的节气</param> public SolarTerm24(SolarTerm24Types jq) { id = jq; }
/// <summary> /// 构造函数 /// </summary> public SolarTerm24() { id = SolarTerm24Types.LiChun; }