public static DateTime GetDateTimeOfSolarTerm(int termIndex, int year) { int[] trialMonths = { 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 1, 1, 2, 2, 3 }; int[] trialDays = { 21, 5, 20, 6, 21, 6, 21, 7, 23, 7, 23, 8, 23, 8, 23, 7, 22, 7, 22, 6, 21, 4, 19, 5 }; double desiredSunLong = termIndex * (Math.PI / 12); DateTime estimatedDateTime = new DateTime(year, trialMonths[termIndex], trialDays[termIndex]); double currentSunLong = Sun.GetSunLongitudeAtJulianDate( estimatedDateTime.UniversalDateTimeToJulianDate()); currentSunLong = Sun.GetSunLongitudeAtJulianDate( estimatedDateTime.UniversalDateTimeToJulianDate()); var error = (currentSunLong - desiredSunLong).ToNormalizedArc(); var direction = 1; if (error > Math.PI) { direction = -1; } double resolution = 1; // days double previousSunLong = currentSunLong; var count = 0; do { estimatedDateTime = estimatedDateTime.AddDays(resolution * direction); currentSunLong = Sun.GetSunLongitudeAtJulianDate(estimatedDateTime.UniversalDateTimeToJulianDate()); double error1 = (currentSunLong - desiredSunLong).ToNormalizedArc(); double error2 = (desiredSunLong + 2 * Math.PI - currentSunLong).ToNormalizedArc(); if (error1 > error && error2 > error) { direction = direction * (-1); resolution = resolution / 2; } error = error1; if (error2 > error1) { error = error1; } else { error = error2; } count++; } while (resolution > (1f / 86400) && Math.Abs(error) > 0.00001); return(estimatedDateTime); }