/// <summary>Calculates time of Equinox and Solstice. /// </summary> /// <param name="year">Year to calculate for</param> /// <param name="season">Event to calculate</param> /// <returns>Date and time event occurs as a fractional Julian Day.</returns> private static double EquinoxSolstice(double year, EquinoxSolsticeEnum season) { double julianEphemerisDay = 0; if (year >= 1000) { var y = (Math.Floor(year) - 2000) / 1000; switch (season) { case EquinoxSolsticeEnum.VernalEquinox: julianEphemerisDay = 2451623.80984 + (365242.37404 * y) + (0.05169 * (y * y)) - (0.00411 * (y * y * y)) - (0.00057 * (y * y * y * y)); break; case EquinoxSolsticeEnum.SummerSolstice: julianEphemerisDay = 2451716.56767 + (365241.62603 * y) + (0.00325 * (y * y)) - (0.00888 * (y * y * y)) - (0.00030 * (y * y * y * y)); break; case EquinoxSolsticeEnum.AutumnalEquinox: julianEphemerisDay = 2451810.21715 + (365242.01767 * y) + (0.11575 * (y * y)) - (0.00337 * (y * y * y)) - (0.00078 * (y * y * y * y)); break; case EquinoxSolsticeEnum.WinterSolstice: julianEphemerisDay = 2451900.05952 + (365242.74049 * y) + (0.06223 * (y * y)) - (0.00823 * (y * y * y)) - (0.00032 * (y * y * y * y)); break; } } else { var y = Math.Floor(year) / 1000; switch (season) { case EquinoxSolsticeEnum.VernalEquinox: julianEphemerisDay = 1721139.29189 + (365242.13740 * y) + (0.06134 * (y * y)) - (0.00111 * (y * y * y)) - (0.00071 * (y * y * y * y)); break; case EquinoxSolsticeEnum.SummerSolstice: julianEphemerisDay = 1721233.25401 + (365241.72562 * y) + (0.05323 * (y * y)) - (0.00907 * (y * y * y)) - (0.00025 * (y * y * y * y)); break; case EquinoxSolsticeEnum.AutumnalEquinox: julianEphemerisDay = 1721325.70455 + (365242.49558 * y) + (0.11677 * (y * y)) - (0.00297 * (y * y * y)) - (0.00074 * (y * y * y * y)); break; case EquinoxSolsticeEnum.WinterSolstice: julianEphemerisDay = 1721414.39987 + (365242.88257 * y) + (0.00769 * (y * y)) - (0.00933 * (y * y * y)) - (0.00006 * (y * y * y * y)); break; } } var julianCenturies = (julianEphemerisDay - 2451545.0) / 36525; var w = (35999.373 * julianCenturies) - 2.47; var lambda = 1 + (0.0334 * Math.Cos(w * Deg2Radian)) + (0.0007 * Math.Cos(2 * w * Deg2Radian)); double Calc(int factor, double v1, double v2) => factor *Math.Cos((Deg2Radian *v1) + (Deg2Radian * (v2 *julianCenturies))); // sum of periodic terms var sum = Calc(485, 324.96, 1934.136) + Calc(203, 337.23, 32964.467) + Calc(199, 342.08, 20.186) + Calc(182, 27.85, 445267.112) + Calc(156, 73.14, 45036.886) + Calc(136, 171.52, 22518.443) + Calc(77, 222.54, 65928.934) + Calc(74, 296.72, 3034.906) + Calc(70, 243.58, 9037.513) + Calc(58, 119.81, 33718.147) + Calc(52, 297.17, 150.678) + Calc(50, 21.02, 2281.226) + Calc(45, 247.54, 29929.562) + Calc(44, 325.15, 31555.956) + Calc(29, 60.93, 4443.417) + Calc(28, 155.12, 67555.328) + Calc(17, 288.79, 4562.452) + Calc(16, 198.04, 62894.029) + Calc(14, 199.76, 31436.921) + Calc(12, 95.39, 14577.848) + Calc(12, 287.11, 31931.756) + Calc(12, 320.81, 34777.259) + Calc(9, 227.73, 1222.114) + Calc(8, 15.45, 16859.074); return(julianEphemerisDay + (0.00001 * sum / lambda)); }
/// <summary>Get the date the equinox or solstice occurs.</summary> /// <param name="year">The year to get the value for</param> /// <param name="season">Equinox or solstice to calculate for.</param> /// <returns>Date and time event occurs.</returns> private static DateTime GetEquinoxSolstice(int year, EquinoxSolsticeEnum season) { return(Julian2Date(EquinoxSolstice(year, season))); }