Example #1
0
        /* Analysation of algorithm of Hồ Ngọc Đức
         * ---------------------------------------
         * double off = LocalToJD(31, 12, Y) - 2415021.076998695;
         *              ^ returns Julian Date of 31st December #Year, 00:00:00 UTC+7
         *                    i.e. 30th December #Year, 17:00:00 UTC
         * int k = INT(off / 29.530588853);
         * double jd = NewMoon(k);
         *             ^ returns the new moon date *time* in Julian Dater, *UTC*
         * int[] ret = LocalFromJD(jd);
         *             ^ converts (jd + timezone/24) back to Calendar Date,
         *                   disregrading the time (i.e. the begining of day in local time zone
         *                   [00:00:00 local] that contains the new moon.)
         *
         * // sun longitude at local midnight
         * double sunLong = SunLongitude(LocalToJD(ret[0], ret[1], ret[2]));
         * if (sunLong > 3 * PI / 2)
         * {
         *     jd = NewMoon(k - 1);
         * }
         * return LocalFromJD(jd);
         * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         * e.g.:
         *       NewMoon(1236) = 2451520.4393767994
         *                     = 7/12/1999 10:32:42 UTC
         *                     = 8/12/1999 17:32:42 UTC+7, thus,
         *
         *  [ Note: UniversalFromJD(2451520.4393767994) = (7, 12, 1999) ]
         *              LocalFromJD(2451520.4393767994) =
         *    UniversalFromJD(JD + LOCAL_TIMEZONE/24.0) = (8, 12, 1999)
         *
         *                       LocalToJD(8, 12, 1999) =
         * UniversalToJD(D, M, Y) - LOCAL_TIMEZONE/24.0 = 8/12/1999 00:00:00 - 7
         * ^                        ^                   = 7/12/1999 17:00:00 UTC <---+
         * |                        +---[ Shift back to local midnight ]             |
         * +---[ Julius Date of D/M/Y 00:00:00 UTC (midnight), 8/12/1999 00:00:00]   |
         *                   [ This value is used to determine the sun longitude ]---+
         */

        /// <summary>
        /// Returns the local date time of the new moon just before
        /// the winter solstice in the given lunar year.
        /// </summary>
        /// <param name="lunarYear"></param>
        /// <param name="timeZone"></param>
        /// <returns></returns>
        public static DateTime GetNewMoon11(int lunarYear, double timeZone)
        {
            // number of days from J1900 to local midnight of 31st December #Year
            // (lunarYear, 12, 31): local
            // (lunarYear, 12, 31, timeZone): universal
            var offset = JulianDateConverter.UniversalDateTimeToJulianDate(lunarYear, 12, 31, timeZone) - Constants.J1900;

            var k = (int)(offset / Constants.SynodicMonth);

            // local date & *time* of new moon
            var newMoonLocalDateTime = JulianDateConverter.JulianDateToUniversalDateTime(GetNewMoon(k)).AddHours(timeZone);
            // beginning of that day (i.e. midnight, i.e. strip off the time)
            var newMoonMidnightLocal = newMoonLocalDateTime.Date;
            // Julian Date at the beginning of that day
            var julianDate =
                newMoonMidnightLocal.AddHours(-timeZone).UniversalDateTimeToJulianDate();

            var sunLongitude = Sun.GetSunLongitudeAtJulianDate(julianDate);

            // Check the winter solstice is after the beginning of that day:
            // If the winter soltice is *before* the beginning of that day,
            //     the previous new moon is the new moon just before winter solstice,
            // else the current new moon is the new moon just before winter solstice.
            if (sunLongitude > (3 * Math.PI / 2))
            {
                newMoonLocalDateTime = JulianDateConverter.JulianDateToUniversalDateTime(GetNewMoon(k - 1)).AddHours(timeZone);
            }

            return(newMoonLocalDateTime);
        }
Example #2
0
        public static int GetSolarTermIndex(DateTime dateTime)
        {
            var julianDate = JulianDateConverter.UniversalDateTimeToJulianDate(dateTime);

            return((int)(GetSunLongitudeAtJulianDate(julianDate) / Math.PI * 12));
        }