示例#1
0
        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);
        }