Ejemplo n.º 1
0
        /// <summary>
        /// Returns the sunrise/sunset times at the given location on the specified day
        /// </summary>
        /// <param name="dt">The requested date/time, utc.  Day/night will be computed based on the time</param>
        private void ComputeTimesAtLocation(DateTime dt)
        {
            if (Latitude > 90 || Latitude < -90)
            {
                throw new MyFlightbookException(Resources.Airports.errInvalidLatitude);
            }
            if (Longitude > 180 || Longitude < -180)
            {
                throw new MyFlightbookException(Resources.Airports.errInvalidLongitude);
            }

            double JD = Solar.calcJD(dt.Year, dt.Month, dt.Day);

            DateTime dtUTC = dt.ToUniversalTime();

            SolarAngle      = Solar.calcSolarAngle(Latitude, Longitude, JD, dtUTC.Hour * 60 + dtUTC.Minute);
            IsFAACivilNight = SolarAngle <= -6.0;

            Boolean nosunrise   = false;
            double  riseTimeGMT = Solar.calcSunriseUTC(JD, Latitude, -Longitude);

            if (double.IsNaN(riseTimeGMT))
            {
                nosunrise = true;
            }

            // Calculate sunset for this date
            // if no sunset is found, set flag nosunset
            Boolean nosunset   = false;
            double  setTimeGMT = Solar.calcSunsetUTC(JD, Latitude, -Longitude);

            if (double.IsNaN(setTimeGMT))
            {
                nosunset = true;
            }

            // we now know the UTC # of minutes for each. Return the UTC sunrise/sunset times
            if (!nosunrise)
            {
                Sunrise = MinutesToDateTime(dt, riseTimeGMT);
            }

            if (!nosunset)
            {
                Sunset = MinutesToDateTime(dt, setTimeGMT);
            }

            // Update daytime/nighttime
            // 3 possible scenarios:
            // (a) time is between sunrise/sunset as computed - it's daytime or FAA daytime.
            // (b) time is after the sunset - figure out the next sunrise and compare to that
            // (c) time is before sunrise - figure out the previous sunset and compare to that
            IsNight             = IsFAACivilNight;
            IsFAANight          = false;
            IsWithinNightOffset = false;
            if (Sunrise.CompareTo(dt) <= 0 && Sunset.CompareTo(dt) >= 0)
            {
                // between sunrise and sunset - it's daytime no matter how you slice it; use default values (set above)
            }
            else if (Sunset.CompareTo(dt) < 0)
            {
                // get the next sunrise.  It is night if the time is between sunset and the next sunrise
                DateTime dtTomorrow = dt.AddDays(1);
                JD = Solar.calcJD(dtTomorrow.Year, dtTomorrow.Month, dtTomorrow.Day);
                double nextSunrise = Solar.calcSunriseUTC(JD, Latitude, -Longitude);
                if (!double.IsNaN(nextSunrise))
                {
                    DateTime dtNextSunrise = MinutesToDateTime(dtTomorrow, nextSunrise);
                    IsNight             = (dtNextSunrise.CompareTo(dt) > 0); // we've already determined that we're after sunset, we just need to be before sunrise
                    IsFAANight          = (Sunset.AddMinutes(NightLandingOffset).CompareTo(dt) <= 0 && dtNextSunrise.AddMinutes(-NightLandingOffset).CompareTo(dt) >= 0);
                    IsWithinNightOffset = (Sunset.AddMinutes(NightFlightOffset).CompareTo(dt) <= 0 && dtNextSunrise.AddMinutes(-NightFlightOffset).CompareTo(dt) >= 0);
                }
            }
            else if (Sunrise.CompareTo(dt) > 0)
            {
                // get the previous sunset.  It is night if the time is between that sunset and the sunrise
                DateTime dtYesterday = dt.AddDays(-1);
                JD = Solar.calcJD(dtYesterday.Year, dtYesterday.Month, dtYesterday.Day);
                double prevSunset = Solar.calcSunsetUTC(JD, Latitude, -Longitude);
                if (!double.IsNaN(prevSunset))
                {
                    DateTime dtPrevSunset = MinutesToDateTime(dtYesterday, prevSunset);
                    IsNight             = (dtPrevSunset.CompareTo(dt) < 0); // we've already determined that we're before sunrise, we just need to be after sunset.
                    IsFAANight          = (dtPrevSunset.AddMinutes(NightLandingOffset).CompareTo(dt) <= 0 && Sunrise.AddMinutes(-NightLandingOffset).CompareTo(dt) >= 0);
                    IsWithinNightOffset = (dtPrevSunset.AddMinutes(NightFlightOffset).CompareTo(dt) <= 0 && Sunrise.AddMinutes(-NightFlightOffset).CompareTo(dt) >= 0);
                }
            }
        }