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)); }
/// <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; } }