예제 #1
0
        /// <summary>
        /// A method that calculates UTC sunrise as well as any time based on an
        /// angle above or below sunrise. This abstract method is implemented by the
        /// classes that extend this class.
        /// </summary>
        /// <param name="dateWithLocation">Used to calculate day of year.</param>
        /// <param name="zenith">the azimuth below the vertical zenith of 90 degrees. for
        /// sunrise typically the <see cref="AstronomicalCalculator.AdjustZenith">zenith</see> used for
        /// the calculation uses geometric zenith of 90°; and
        /// <see cref="AstronomicalCalculator.AdjustZenith">adjusts</see> this slightly to account for
        /// solar refraction and the sun's radius. Another example would
        /// be <see cref="AstronomicalCalendar.GetBeginNauticalTwilight"/>
        /// that passes <see cref="AstronomicalCalendar.NAUTICAL_ZENITH"/> to
        /// this method.</param>
        /// <param name="adjustForElevation">if set to <c>true</c> [adjust for elevation].</param>
        /// <returns>
        /// The UTC time of sunrise in 24 hour format. 5:45:00 AM will return
        /// 5.75.0. If an error was encountered in the calculation (expected
        /// behavior for some locations such as near the poles,
        /// <see cref="Double.NaN"/> will be returned.
        /// </returns>
        /// <seealso cref="AstronomicalCalculator.GetUtcSunrise"/>
        public override double GetUtcSunrise(IDateWithLocation dateWithLocation, double zenith,
                                             bool adjustForElevation)
        {
            /*if (dateWithLocation.Date.Year <= 2000)
             * {
             *  throw new Exception("NOAACalculator can not calculate times earlier than the year 2000.	Please try a date with a different year.");
             * }*/

            zenith = AdjustZenith(zenith, adjustForElevation ? dateWithLocation.Location.Elevation : 0);

            double sunrise = CalcSunriseUtc(CalcJulianDay(dateWithLocation),
                                            dateWithLocation.Location.Latitude,
                                            -dateWithLocation.Location.Longitude, zenith);

            sunrise = sunrise / 60;

            // ensure that the time is >= 0 and < 24
            while (sunrise < 0.0)
            {
                sunrise += 24.0;
            }
            while (sunrise >= 24.0)
            {
                sunrise -= 24.0;
            }
            return(sunrise);
        }
예제 #2
0
        ///<summary>
        ///  The date:date-time function returns the current date and time as a
        ///  date/time string. The date/time string that's returned must be a string
        ///  in the format defined as the lexical representation of xs:Date in
        ///  <a href = "http://www.w3.org/TR/xmlschema11-2/#Date">[3.3.8 Date]</a>
        ///  of <a href = "http://www.w3.org/TR/xmlschema11-2/">[XML Schema 1.1 Part 2:
        ///       Datatypes]</a>. The date/time format is basically CCYY-MM-DDThh:mm:ss,
        ///  although implementers should consult <a href = "http://www.w3.org/TR/xmlschema11-2/">[XML Schema 1.1 Part 2:
        ///                                         Datatypes]</a> and <a href = "http://www.iso.ch/markete/8601.pdf">[ISO
        ///                                                              8601]</a> for details. The date/time string format must include a time
        ///  zone, either a Z to indicate Coordinated Universal Time or a + or -
        ///  followed by the difference between the difference from UTC represented as
        ///  hh:mm.
        ///</summary>
        public virtual string GetXSDate(DateTime date, IDateWithLocation cal)
        {
            string xsdDateFormat = "yyyy-MM-dd'T'HH:mm:ss";
            //
            //		 * if (xmlDateFormat == null || xmlDateFormat.trim().equals("")) {
            //		 * xmlDateFormat = xsdDateFormat; }
            //
            //var dateFormat = new SimpleDateFormat(xsdDateFormat);

            var buff = new StringBuilder(date.ToString(xsdDateFormat));
            // Must also include offset from UTF.
            // Get the offset (in milliseconds).
            int offset = cal.Location.TimeZone.UtcOffset(cal.Date);

            // If there is no offset, we have "Coordinated
            // Universal Time."
            if (offset == 0)
            {
                buff.Append("Z");
            }
            else
            {
                // Convert milliseconds to hours and minutes
                int hrs = offset / (60 * 60 * 1000);
                // In a few cases, the time zone may be +/-hh:30.
                int  min    = offset % (60 * 60 * 1000);
                char posneg = hrs < 0 ? '-' : '+';
                buff.Append(posneg + FormatDigits(hrs) + ':' + FormatDigits(min));
            }
            return(buff.ToString());
        }
예제 #3
0
        /// <summary>
        /// A method that calculates UTC sunrise as well as any time based on an
        /// angle above or below sunrise. This abstract method is implemented by the
        /// classes that extend this class.
        /// </summary>
        /// <param name="dateWithLocation">Used to calculate day of year.</param>
        /// <param name="zenith">the azimuth below the vertical zenith of 90 degrees. for
        /// sunrise typically the <see cref="AstronomicalCalculator.AdjustZenith">zenith</see> used for
        /// the calculation uses geometric zenith of 90°; and
        /// <see cref="AstronomicalCalculator.AdjustZenith">adjusts</see> this slightly to account for
        /// solar refraction and the sun's radius. Another example would
        /// be <see cref="AstronomicalCalendar.GetBeginNauticalTwilight"/>
        /// that passes <see cref="AstronomicalCalendar.NAUTICAL_ZENITH"/> to
        /// this method.</param>
        /// <param name="adjustForElevation">if set to <c>true</c> [adjust for elevation].</param>
        /// <returns>
        /// The UTC time of sunrise in 24 hour format. 5:45:00 AM will return
        /// 5.75.0. If an error was encountered in the calculation (expected
        /// behavior for some locations such as near the poles,
        /// <see cref="Double.NaN"/> will be returned.
        /// </returns>
        /// <seealso cref="AstronomicalCalculator.GetUtcSunrise"/>
        public override double GetUtcSunrise(IDateWithLocation dateWithLocation, double zenith,
                                             bool adjustForElevation)
        {
            /*if (dateWithLocation.Date.Year <= 2000)
            {
                throw new Exception("NOAACalculator can not calculate times earlier than the year 2000.	Please try a date with a different year.");
            }*/

            zenith = AdjustZenith(zenith, adjustForElevation ? dateWithLocation.Location.Elevation : 0);

            double sunrise = CalcSunriseUtc(CalcJulianDay(dateWithLocation),
                                            dateWithLocation.Location.Latitude,
                                            -dateWithLocation.Location.Longitude, zenith);
            sunrise = sunrise / 60;

            // ensure that the time is >= 0 and < 24
            while (sunrise < 0.0)
            {
                sunrise += 24.0;
            }
            while (sunrise >= 24.0)
            {
                sunrise -= 24.0;
            }
            return sunrise;
        }
예제 #4
0
        /// <summary>
        /// A method that calculates UTC sunrise as well as any time based on an
        /// angle above or below sunrise. This abstract method is implemented by the
        /// classes that extend this class.
        /// </summary>
        /// <param name="dateWithLocation">Used to calculate day of year.</param>
        /// <param name="zenith">the azimuth below the vertical zenith of 90 degrees. for
        /// sunrise typically the <see cref="AstronomicalCalculator.AdjustZenith">zenith</see> used for
        /// the calculation uses geometric zenith of 90°; and
        /// <see cref="AstronomicalCalculator.AdjustZenith">adjusts</see> this slightly to account for
        /// solar refraction and the sun's radius. Another example would
        /// be <see cref="AstronomicalCalendar.GetBeginNauticalTwilight"/>
        /// that passes <see cref="AstronomicalCalendar.NAUTICAL_ZENITH"/> to
        /// this method.</param>
        /// <param name="adjustForElevation">if set to <c>true</c> [adjust for elevation].</param>
        /// <returns>
        /// The UTC time of sunrise in 24 hour format. 5:45:00 AM will return
        /// 5.75.0. If an error was encountered in the calculation (expected
        /// behavior for some locations such as near the poles,
        /// <see cref="Double.NaN"/> will be returned.
        /// </returns>
        /// <seealso cref="AstronomicalCalculator.GetUtcSunrise"/>
        public override double GetUtcSunrise(IDateWithLocation dateWithLocation, double zenith,
                                             bool adjustForElevation)
        {
            double elevation = adjustForElevation ? dateWithLocation.Location.Elevation : 0;

            return(GetTimeUtc(
                       dateWithLocation.Date,
                       dateWithLocation.Location,
                       AdjustZenith(zenith, elevation),
                       true));
        }
예제 #5
0
 ///<summary>
 ///  Formats a date using this classe's <see cref = "DateFormat">date format</see>.
 ///</summary>
 ///<param name = "date">
 ///  the date to format </param>
 ///<param name = "dateWithLocation">
 ///  the <see cref = "IDateWithLocation">TimeZone and DateTime</see> used to help format
 ///  based on the Calendar's DST and other settings. </param>
 ///<returns> the formatted string </returns>
 public virtual string FormatDate(DateTime date, IDateWithLocation dateWithLocation)
 {
     if (DateFormat == "yyyy-MM-dd'T'HH:mm:ss")
     {
         return(GetXSDate(date, dateWithLocation));
     }
     else
     {
         return(date.ToString(DateFormat));
     }
 }
예제 #6
0
        ///<summary>
        ///  Generate a Julian day from Java Calendar
        ///</summary>
        ///<param name = "date">
        ///  Java Calendar </param>
        ///<returns> the Julian day corresponding to the date Note: Number is returned
        ///  for start of day. Fractional days should be added later. </returns>
        private static double CalcJd(IDateWithLocation date)
        {
            int year  = date.Date.Year;
            int month = date.Date.Month + 1;
            int day   = date.Date.Day;

            if (month <= 2)
            {
                year  -= 1;
                month += 12;
            }
            double A = Math.Floor((double)(year / 100));
            double B = 2 - A + Math.Floor(A / 4);

            return(Math.Floor(365.25 * (year + 4716)) + Math.Floor(30.6001 * (month + 1)) + day + B - 1524.5);
        }
예제 #7
0
        private static double DateToJulian(IDateWithLocation date)
        {
            int year   = date.Date.Year;
            int month  = date.Date.Month;
            int day    = date.Date.Day;
            int hour   = date.Date.Hour;
            int minute = date.Date.Minute;
            int second = date.Date.Second;

            double extra = (100.0 * year) + month - 190002.5;
            double JD    = (367.0 * year) - (Math.Floor(7.0 * (year + Math.Floor((month + 9.0) / 12.0)) / 4.0)) +
                           Math.Floor((275.0 * month) / 9.0) + day + ((hour + ((minute + (second / 60.0)) / 60.0)) / 24.0) +
                           1721013.5 - ((0.5 * extra) / Math.Abs(extra)) + 0.5;

            return(JD);
        }
예제 #8
0
        /// <summary>
        /// Return the <a href="http://en.wikipedia.org/wiki/Celestial_coordinate_system">Solar Elevation</a> for the
        /// horizontal coordinate system at the given location at the given time.Can be negative if the sun is below the
        /// horizon.Not corrected for altitude.
        ///
        /// <param name="dateWithLocation">the date with location</param>
        public static double GetSolarElevation(IDateWithLocation dateWithLocation)
        {
            double julianDay       = GetJulianDay(dateWithLocation.Date);
            double julianCenturies = GetJulianCenturiesFromJulianDay(julianDay);

            double eot = GetEquationOfTime(julianCenturies);

            double longitude = (dateWithLocation.Date.Hour + 12.0)
                               + (dateWithLocation.Date.Minute + eot + dateWithLocation.Date.Second / 60.0) / 60.0;

            longitude = -(longitude * 360.0 / 24.0) % 360.0;
            double hourAngle_rad = (dateWithLocation.Location.Longitude - longitude).ToRadians();
            double declination   = GetSunDeclination(julianCenturies);
            double dec_rad       = declination.ToRadians();
            double lat_rad       = dateWithLocation.Location.Latitude.ToRadians();

            return(Math.Asin((Math.Sin(lat_rad) * Math.Sin(dec_rad))
                             + (Math.Cos(lat_rad) * Math.Cos(dec_rad) * Math.Cos(hourAngle_rad))).ToDegree());
        }
예제 #9
0
        /// <summary>
        /// A method that calculates UTC sunrise as well as any time based on an
        /// angle above or below sunrise. This abstract method is implemented by the
        /// classes that extend this class.
        /// </summary>
        /// <param name="astronomicalCalendar">Used to calculate day of year.</param>
        /// <param name="zenith">the azimuth below the vertical zenith of 90 degrees. for
        /// sunrise typically the <see cref="AstronomicalCalculator.AdjustZenith">zenith</see> used for
        /// the calculation uses geometric zenith of 90°; and
        /// <see cref="AstronomicalCalculator.AdjustZenith">adjusts</see> this slightly to account for
        /// solar refraction and the sun's radius. Another example would
        /// be <see cref="AstronomicalCalendar.GetBeginNauticalTwilight"/>
        /// that passes <see cref="AstronomicalCalendar.NAUTICAL_ZENITH"/> to
        /// this method.</param>
        /// <param name="adjustForElevation">if set to <c>true</c> [adjust for elevation].</param>
        /// <returns>
        /// The UTC time of sunrise in 24 hour format. 5:45:00 AM will return
        /// 5.75.0. If an error was encountered in the calculation (expected
        /// behavior for some locations such as near the poles,
        /// <see cref="Double.NaN"/> will be returned.
        /// </returns>
        /// <seealso cref="AstronomicalCalculator.GetUtcSunrise"/>
        public override double GetUtcSunrise(IDateWithLocation dateWithLocation, double zenith,
                                             bool adjustForElevation)
        {
            double doubleTime = double.NaN;

            if (adjustForElevation)
            {
                zenith = AdjustZenith(zenith, dateWithLocation.Location.Elevation);
            }
            else
            {
                zenith = AdjustZenith(zenith, 0);
            }
            doubleTime = GetTimeUtc(dateWithLocation.Date.Year,
                                    dateWithLocation.Date.Month,
                                    dateWithLocation.Date.Day,
                                    dateWithLocation.Location.Longitude,
                                    dateWithLocation.Location.Latitude, zenith, TYPE_SUNRISE);
            return(doubleTime);
        }
예제 #10
0
        /// <summary>
        /// A method that calculates UTC sunrise as well as any time based on an
        /// angle above or below sunrise. This abstract method is implemented by the
        /// classes that extend this class.
        /// </summary>
        /// <param name="dateWithLocation">Used to calculate day of year.</param>
        /// <param name="zenith">the azimuth below the vertical zenith of 90 degrees. for
        /// sunrise typically the <see cref="AstronomicalCalculator.AdjustZenith">zenith</see> used for
        /// the calculation uses geometric zenith of 90°; and
        /// <see cref="AstronomicalCalculator.AdjustZenith">adjusts</see> this slightly to account for
        /// solar refraction and the sun's radius. Another example would
        /// be <see cref="AstronomicalCalendar.GetBeginNauticalTwilight"/>
        /// that passes <see cref="AstronomicalCalendar.NAUTICAL_ZENITH"/> to
        /// this method.</param>
        /// <param name="adjustForElevation">if set to <c>true</c> [adjust for elevation].</param>
        /// <returns>
        /// The UTC time of sunrise in 24 hour format. 5:45:00 AM will return
        /// 5.75.0. If an error was encountered in the calculation (expected
        /// behavior for some locations such as near the poles,
        /// <see cref="Double.NaN"/> will be returned.
        /// </returns>
        /// <seealso cref="AstronomicalCalculator.GetUtcSunrise"/>
        public override double GetUtcSunrise(IDateWithLocation dateWithLocation, double zenith,
                                             bool adjustForElevation)
        {
            double adjustedZenith = AdjustZenith(zenith, adjustForElevation ? dateWithLocation.Location.Elevation : 0);

            double sunrise = GetSunriseUTC(GetJulianDay(dateWithLocation.Date),
                                           dateWithLocation.Location.Latitude,
                                           -dateWithLocation.Location.Longitude, adjustedZenith);

            sunrise = sunrise / 60;

            // ensure that the time is >= 0 and < 24
            while (sunrise < 0.0)
            {
                sunrise += 24.0;
            }
            while (sunrise >= 24.0)
            {
                sunrise -= 24.0;
            }
            return(sunrise);
        }
예제 #11
0
        /// <summary>
        /// A method that calculates UTC sunset as well as any time based on an angle
        /// above or below sunset. This abstract method is implemented by the classes
        /// that extend this class.
        /// </summary>
        /// <param name="astronomicalCalendar">Used to calculate day of year.</param>
        /// <param name="zenith">the azimuth below the vertical zenith of 90°;. For sunset
        /// typically the <see cref="AstronomicalCalculator.AdjustZenith">zenith</see> used for the
        /// calculation uses geometric zenith of 90°; and
        /// <see cref="AstronomicalCalculator.AdjustZenith">adjusts</see> this slightly to account for
        /// solar refraction and the sun's radius. Another example would
        /// be <see cref="AstronomicalCalendar.GetEndNauticalTwilight"/> that
        /// passes <see cref="AstronomicalCalendar.NAUTICAL_ZENITH"/> to this
        /// method.</param>
        /// <param name="adjustForElevation"></param>
        /// <returns>
        /// The UTC time of sunset in 24 hour format. 5:45:00 AM will return
        /// 5.75.0. If an error was encountered in the calculation (expected
        /// behavior for some locations such as near the poles,
        /// <seealso cref="Double.NaN"/> will be returned.
        /// </returns>
        /// <seealso cref="AstronomicalCalculator.GetUtcSunset"/>
        public override double GetUtcSunset(IDateWithLocation dateWithLocation, double zenith,
                                            bool adjustForElevation)
        {
            // if (astronomicalCalendar.getCalendar().get(Calendar.YEAR) <= 2000) {
            // throw new ZmanimException(
            // "NOAACalculator can not calculate times for the year 2000. Please try
            // a date with a different year.");
            // }


            if (adjustForElevation)
            {
                zenith = AdjustZenith(zenith, dateWithLocation.Location.Elevation);
            }
            else
            {
                zenith = AdjustZenith(zenith, 0);
            }

            double sunset = CalcSunsetUtc(CalcJulianDay(dateWithLocation),
                                          dateWithLocation.Location.Latitude,
                                          -dateWithLocation.Location.Longitude, zenith);

            sunset = sunset / 60;

            // ensure that the time is >= 0 and < 24
            while (sunset < 0.0)
            {
                sunset += 24.0;
            }
            while (sunset >= 24.0)
            {
                sunset -= 24.0;
            }
            return(sunset);
        }
예제 #12
0
        /// <summary>
        /// A method that calculates UTC sunset as well as any time based on an angle
        /// above or below sunset. This abstract method is implemented by the classes
        /// that extend this class.
        /// </summary>
        /// <param name="dateWithLocation">Used to calculate day of year.</param>
        /// <param name="zenith">the azimuth below the vertical zenith of 90°;. For sunset
        /// typically the <see cref="AstronomicalCalculator.AdjustZenith">zenith</see> used for the
        /// calculation uses geometric zenith of 90°; and
        /// <see cref="AstronomicalCalculator.AdjustZenith">adjusts</see> this slightly to account for
        /// solar refraction and the sun's radius. Another example would
        /// be <see cref="AstronomicalCalendar.GetEndNauticalTwilight"/> that
        /// passes <see cref="AstronomicalCalendar.NAUTICAL_ZENITH"/> to this
        /// method.</param>
        /// <param name="adjustForElevation"></param>
        /// <returns>
        /// The UTC time of sunset in 24 hour format. 5:45:00 AM will return
        /// 5.75.0. If an error was encountered in the calculation (expected
        /// behavior for some locations such as near the poles,
        /// <seealso cref="Double.NaN"/> will be returned.
        /// </returns>
        /// <seealso cref="AstronomicalCalculator.GetUtcSunset"/>
        public override double GetUtcSunset(IDateWithLocation dateWithLocation, double zenith,
                                            bool adjustForElevation)
        {
            double elevation = adjustForElevation ? dateWithLocation.Location.Elevation : 0;

            double sunset = GetSunsetUTC(
                GetJulianDay(dateWithLocation.Date),
                dateWithLocation.Location.Latitude, -dateWithLocation.Location.Longitude,
                AdjustZenith(zenith, elevation)
                );

            sunset = sunset / 60;

            // ensure that the time is >= 0 and < 24
            while (sunset < 0.0)
            {
                sunset += 24.0;
            }
            while (sunset >= 24.0)
            {
                sunset -= 24.0;
            }
            return(sunset);
        }
예제 #13
0
        private static double DateToJulian(IDateWithLocation date)
        {
            int year = date.Date.Year;
            int month = date.Date.Month;
            int day = date.Date.Day;
            int hour = date.Date.Hour;
            int minute = date.Date.Minute;
            int second = date.Date.Second;

            double extra = (100.0*year) + month - 190002.5;
            double JD = (367.0*year) - (Math.Floor(7.0*(year + Math.Floor((month + 9.0)/12.0))/4.0)) +
                        Math.Floor((275.0*month)/9.0) + day + ((hour + ((minute + (second/60.0))/60.0))/24.0) +
                        1721013.5 - ((0.5*extra)/Math.Abs(extra)) + 0.5;
            return JD;
        }
예제 #14
0
        private double GetUtcSunriseSunset(
            IDateWithLocation dateWithLocation, double zenith, bool adjustForElevation, bool isSunrise)
        {
            double elevation      = adjustForElevation ? dateWithLocation.Location.Elevation : 0;
            double adjustedZenith = AdjustZenith(zenith, elevation);

            // step 1: First calculate the day of the year
            int dayOfYear = dateWithLocation.Date.DayOfYear;

            // step 2: convert the longitude to hour value and calculate an
            // approximate time
            double lngHour = dateWithLocation.Location.Longitude / 15;

            double t = dayOfYear + (((isSunrise ? 6 : 18) - lngHour) / 24);

            // step 3: calculate the sun's mean anomaly
            double meanAnomaly = (0.9856 * t) - 3.289;

            // step 4: calculate the sun's true longitude
            double trueLongitude =
                meanAnomaly + (1.916 * Math.Sin(meanAnomaly.ToRadians()))
                + (0.020 * Math.Sin((2 * meanAnomaly).ToRadians())) + 282.634;

            while (trueLongitude < 0)
            {
                trueLongitude = trueLongitude + 360;
            }
            while (trueLongitude >= 360)
            {
                trueLongitude = trueLongitude - 360;
            }

            // step 5a: calculate the sun's right ascension
            double rAscension = Math.Atan(0.91764 * Math.Tan(trueLongitude.ToRadians())).ToDegree();

            while (rAscension < 0)
            {
                rAscension = rAscension + 360;
            }
            while (rAscension >= 360)
            {
                rAscension = rAscension - 360;
            }

            // step 5b: right ascension value needs to be in the same quadrant as L
            double lQuadrant = Math.Floor(trueLongitude / 90) * 90;
            double rQuadrant = Math.Floor(rAscension / 90) * 90;

            rAscension = rAscension + (lQuadrant - rQuadrant);

            // step 5c: right ascension value needs to be converted into hours
            rAscension /= 15;

            // step 6: calculate the sun's declination
            double sinDec = 0.39782 * Math.Sin(trueLongitude.ToRadians());
            double cosDec = Math.Cos(Math.Asin(sinDec));

            var latitudeRadians = dateWithLocation.Location.Latitude.ToRadians();

            // step 7a: calculate the sun's local hour angle
            double cosH = (Math.Cos(adjustedZenith.ToRadians()) -
                           (sinDec * Math.Sin(latitudeRadians))) /
                          (cosDec * Math.Cos(latitudeRadians));

            // step 7b: finish calculating H and convert into hours
            double hours = Math.Acos(cosH).ToDegree();

            if (isSunrise)
            {
                hours = 360 - hours;
            }

            hours = hours / 15;

            // step 8: calculate local mean time

            double localMeanTime = hours + rAscension - (0.06571 * t) - 6.622;

            // step 9: convert to UTC
            double utc = localMeanTime - lngHour;

            while (utc < 0)
            {
                utc = utc + 24;
            }
            while (utc >= 24)
            {
                utc = utc - 24;
            }

            return(utc);
        }
예제 #15
0
        /// <summary>
        /// A method that calculates UTC sunrise as well as any time based on an
        /// angle above or below sunrise. This abstract method is implemented by the
        /// classes that extend this class.
        /// </summary>
        /// <param name="astronomicalCalendar">Used to calculate day of year.</param>
        /// <param name="zenith">the azimuth below the vertical zenith of 90 degrees. for
        /// sunrise typically the <see cref="AstronomicalCalculator.AdjustZenith">zenith</see> used for
        /// the calculation uses geometric zenith of 90°; and
        /// <see cref="AstronomicalCalculator.AdjustZenith">adjusts</see> this slightly to account for
        /// solar refraction and the sun's radius. Another example would
        /// be <see cref="AstronomicalCalendar.GetBeginNauticalTwilight"/>
        /// that passes <see cref="AstronomicalCalendar.NAUTICAL_ZENITH"/> to
        /// this method.</param>
        /// <param name="adjustForElevation"></param>
        /// <returns>
        /// The UTC time of sunrise in 24 hour format. 5:45:00 AM will return
        /// 5.75.0. If an error was encountered in the calculation (expected
        /// behavior for some locations such as near the poles,
        /// <see cref="Double.NaN"/> will be returned.
        /// </returns>
        public override double GetUtcSunrise(IDateWithLocation dateWithLocation, double zenith,
                                             bool adjustForElevation)
        {
            // zenith = adjustZenithForElevation(astronomicalCalendar, zenith,
            // geoLocation.getElevation());
            // double elevationAdjustment = this.getElevationAdjustment(zenith,
            // geoLocation.getElevation());
            // double refractionAdjustment = this.getRefraction(zenith);
            // zenith = zenith + elevationAdjustment + refractionAdjustment;
            if (adjustForElevation)
                zenith = AdjustZenith(zenith, dateWithLocation.Location.Elevation);
            else
                zenith = AdjustZenith(zenith, 0);

            // step 1: First calculate the day of the year
            // NOT NEEDED in this implementation

            // step 2: convert the longitude to hour value and calculate an
            // approximate time
            double lngHour = dateWithLocation.Location.Longitude / 15;

            double t = dateWithLocation.Date.DayOfYear + ((6 - lngHour) / 24); // use 18 for
            // sunset instead
            // of 6

            // step 3: calculate the sun's mean anomaly
            double m = (0.9856*t) - 3.289;

            // step 4: calculate the sun's true longitude
            double l = m + (1.916*Math.Sin(MathExtensions.ToRadians(m))) + (0.020*Math.Sin(MathExtensions.ToRadians(2*m))) +
                       282.634;
            while (l < 0)
            {
                double Lx = l + 360;
                l = Lx;
            }
            while (l >= 360)
            {
                double Lx = l - 360;
                l = Lx;
            }

            // step 5a: calculate the sun's right ascension
            double RA = MathExtensions.ToDegree(Math.Atan(0.91764*Math.Tan(MathExtensions.ToRadians(l))));

            while (RA < 0)
            {
                double RAx = RA + 360;
                RA = RAx;
            }
            while (RA >= 360)
            {
                double RAx = RA - 360;
                RA = RAx;
            }

            // step 5b: right ascension value needs to be in the same quadrant as L
            double lQuadrant = Math.Floor(l/90)*90;
            double raQuadrant = Math.Floor(RA/90)*90;
            RA = RA + (lQuadrant - raQuadrant);

            // step 5c: right ascension value needs to be converted into hours
            RA /= 15;

            // step 6: calculate the sun's declination
            double sinDec = 0.39782*Math.Sin(MathExtensions.ToRadians(l));
            double cosDec = Math.Cos(Math.Asin(sinDec));

            // step 7a: calculate the sun's local hour angle
            double cosH = (Math.Cos(MathExtensions.ToRadians(zenith)) -
                           (sinDec * Math.Sin(MathExtensions.ToRadians(dateWithLocation.Location.Latitude)))) /
                          (cosDec * Math.Cos(MathExtensions.ToRadians(dateWithLocation.Location.Latitude)));

            // the following line would throw an Exception if the sun never rose.
            // this is not needed since the calculation will return a Double.NaN
            // if (cosH > 1) throw new Exception("doesnthappen");

            // FOR SUNSET use the following instead of the above if statement.
            // if (cosH < -1)

            // step 7b: finish calculating H and convert into hours
            double H = 360 - MathExtensions.ToDegree(Math.Acos(cosH));

            // FOR SUNSET remove "360 - " from the above

            H = H/15;

            // step 8: calculate local mean time

            double T = H + RA - (0.06571*t) - 6.622;

            // step 9: convert to UTC
            double UT = T - lngHour;
            while (UT < 0)
            {
                double UTx = UT + 24;
                UT = UTx;
            }
            while (UT >= 24)
            {
                double UTx = UT - 24;
                UT = UTx;
            }
            return UT;
        }
예제 #16
0
 /// <summary>
 /// A method that calculates UTC sunset as well as any time based on an angle
 /// above or below sunset. This abstract method is implemented by the classes
 /// that extend this class.
 /// </summary>
 /// <param name="astronomicalCalendar">Used to calculate day of year.</param>
 /// <param name="zenith">the azimuth below the vertical zenith of 90°;. For sunset
 /// typically the <see cref="AstronomicalCalculator.AdjustZenith">zenith</see> used for the
 /// calculation uses geometric zenith of 90°; and
 /// <see cref="AstronomicalCalculator.AdjustZenith">adjusts</see> this slightly to account for
 /// solar refraction and the sun's radius. Another example would
 /// be <see cref="AstronomicalCalendar.GetEndNauticalTwilight"/> that
 /// passes <see cref="AstronomicalCalendar.NAUTICAL_ZENITH"/> to this
 /// method.</param>
 /// <param name="adjustForElevation">if set to <c>true</c> [adjust for elevation].</param>
 /// <returns>
 /// The UTC time of sunset in 24 hour format. 5:45:00 AM will return
 /// 5.75.0. If an error was encountered in the calculation (expected
 /// behavior for some locations such as near the poles,
 /// <seealso cref="Double.NaN"/> will be returned.
 /// </returns>
 public abstract double GetUtcSunset(IDateWithLocation dateWithLocation, double zenith, bool adjustForElevation);
예제 #17
0
        ///<summary>
        ///  Generate a Julian day from a .NET date
        ///</summary>
        ///<param name = "date">
        ///  Java Calendar </param>
        ///<returns> the Julian day corresponding to the date Note: Number is returned
        ///  for start of day. Fractional days should be added later. </returns>
        private static double CalcJulianDay(IDateWithLocation dateWithLocation)
        {
            var date = dateWithLocation.Date;

            return new DateTime(date.Year, date.Month, date.Day).ToOADate() + 2415018.5;
        }
예제 #18
0
 /// <summary>
 /// Initializes a new instance of the <see cref="AstronomicalCalendar"/> class.
 /// </summary>
 /// <param name="dateWithLocation">The date with location.</param>
 public AstronomicalCalendar(IDateWithLocation dateWithLocation)
 {
     DateWithLocation = dateWithLocation;
     AstronomicalCalculator = Calculator.AstronomicalCalculator.GetDefault();
 }
예제 #19
0
 ///<summary>
 ///  Formats a date using this classe's <see cref = "DateFormat">date format</see>.
 ///</summary>
 ///<param name = "date">
 ///  the date to format </param>
 ///<param name = "dateWithLocation">
 ///  the <see cref = "IDateWithLocation">TimeZone and DateTime</see> used to help format
 ///  based on the Calendar's DST and other settings. </param>
 ///<returns> the formatted string </returns>
 public virtual string FormatDate(DateTime date, IDateWithLocation dateWithLocation)
 {
     if (DateFormat == "yyyy-MM-dd'T'HH:mm:ss")
     {
         return GetXSDate(date, dateWithLocation);
     }
     else
     {
         return date.ToString(DateFormat);
     }
 }
예제 #20
0
        ///<summary>
        ///  Generate a Julian day from a .NET date
        ///</summary>
        ///<param name = "date">
        ///  Java Calendar </param>
        ///<returns> the Julian day corresponding to the date Note: Number is returned
        ///  for start of day. Fractional days should be added later. </returns>
        private static double CalcJulianDay(IDateWithLocation dateWithLocation)
        {
            var date = dateWithLocation.Date;

            return(new DateTime(date.Year, date.Month, date.Day).ToOADate() + 2415018.5);
        }
예제 #21
0
        /// <summary>
        /// A method that calculates UTC sunset as well as any time based on an angle
        /// above or below sunset. This abstract method is implemented by the classes
        /// that extend this class.
        /// </summary>
        /// <param name="astronomicalCalendar">Used to calculate day of year.</param>
        /// <param name="zenith">the azimuth below the vertical zenith of 90°;. For sunset
        /// typically the <see cref="AstronomicalCalculator.AdjustZenith">zenith</see> used for the
        /// calculation uses geometric zenith of 90°; and
        /// <see cref="AstronomicalCalculator.AdjustZenith">adjusts</see> this slightly to account for
        /// solar refraction and the sun's radius. Another example would
        /// be <see cref="AstronomicalCalendar.GetEndNauticalTwilight"/> that
        /// passes <see cref="AstronomicalCalendar.NAUTICAL_ZENITH"/> to this
        /// method.</param>
        /// <param name="adjustForElevation"></param>
        /// <returns>
        /// The UTC time of sunset in 24 hour format. 5:45:00 AM will return
        /// 5.75.0. If an error was encountered in the calculation (expected
        /// behavior for some locations such as near the poles,
        /// <seealso cref="Double.NaN"/> will be returned.
        /// </returns>
        /// <seealso cref="AstronomicalCalculator.GetUtcSunset"/>
        public override double GetUtcSunset(IDateWithLocation dateWithLocation, double zenith,
                                            bool adjustForElevation)
        {
            // if (astronomicalCalendar.getCalendar().get(Calendar.YEAR) <= 2000) {
            // throw new ZmanimException(
            // "NOAACalculator can not calculate times for the year 2000. Please try
            // a date with a different year.");
            // }

            if (adjustForElevation)
            {
                zenith = AdjustZenith(zenith, dateWithLocation.Location.Elevation);
            }
            else
            {
                zenith = AdjustZenith(zenith, 0);
            }

            double sunset = CalcSunsetUtc(CalcJulianDay(dateWithLocation),
                                          dateWithLocation.Location.Latitude,
                                          -dateWithLocation.Location.Longitude, zenith);
            sunset = sunset / 60;

            // ensure that the time is >= 0 and < 24
            while (sunset < 0.0)
            {
                sunset += 24.0;
            }
            while (sunset >= 24.0)
            {
                sunset -= 24.0;
            }
            return sunset;
        }
예제 #22
0
        /// <summary>
        /// A method that calculates UTC sunrise as well as any time based on an
        /// angle above or below sunrise. This abstract method is implemented by the
        /// classes that extend this class.
        /// </summary>
        /// <param name="astronomicalCalendar">Used to calculate day of year.</param>
        /// <param name="zenith">the azimuth below the vertical zenith of 90 degrees. for
        /// sunrise typically the <see cref="AstronomicalCalculator.AdjustZenith">zenith</see> used for
        /// the calculation uses geometric zenith of 90°; and
        /// <see cref="AstronomicalCalculator.AdjustZenith">adjusts</see> this slightly to account for
        /// solar refraction and the sun's radius. Another example would
        /// be <see cref="AstronomicalCalendar.GetBeginNauticalTwilight"/>
        /// that passes <see cref="AstronomicalCalendar.NAUTICAL_ZENITH"/> to
        /// this method.</param>
        /// <param name="adjustForElevation">if set to <c>true</c> [adjust for elevation].</param>
        /// <returns>
        /// The UTC time of sunrise in 24 hour format. 5:45:00 AM will return
        /// 5.75.0. If an error was encountered in the calculation (expected
        /// behavior for some locations such as near the poles,
        /// <see cref="Double.NaN"/> will be returned.
        /// </returns>
        /// <seealso cref="AstronomicalCalculator.GetUtcSunrise"/>
        public override double GetUtcSunrise(IDateWithLocation dateWithLocation, double zenith,
                                             bool adjustForElevation)
        {
            double doubleTime = double.NaN;

            if (adjustForElevation)
            {
                zenith = AdjustZenith(zenith, dateWithLocation.Location.Elevation);
            }
            else
            {
                zenith = AdjustZenith(zenith, 0);
            }
            doubleTime = GetTimeUtc(dateWithLocation.Date.Year,
                                    dateWithLocation.Date.Month,
                                    dateWithLocation.Date.Day,
                                    dateWithLocation.Location.Longitude,
                                    dateWithLocation.Location.Latitude, zenith, TYPE_SUNRISE);
            return doubleTime;
        }
예제 #23
0
 /// <summary>
 /// Initializes a new instance of the <see cref="AstronomicalCalendar"/> class.
 /// </summary>
 /// <param name="dateWithLocation">The date with location.</param>
 public AstronomicalCalendar(IDateWithLocation dateWithLocation)
 {
     DateWithLocation       = dateWithLocation;
     AstronomicalCalculator = Calculator.AstronomicalCalculator.GetDefault();
 }
예제 #24
0
        ///<summary>
        ///  The date:date-time function returns the current date and time as a
        ///  date/time string. The date/time string that's returned must be a string
        ///  in the format defined as the lexical representation of xs:Date in
        ///  <a href = "http://www.w3.org/TR/xmlschema11-2/#Date">[3.3.8 Date]</a>
        ///  of <a href = "http://www.w3.org/TR/xmlschema11-2/">[XML Schema 1.1 Part 2:
        ///       Datatypes]</a>. The date/time format is basically CCYY-MM-DDThh:mm:ss,
        ///  although implementers should consult <a href = "http://www.w3.org/TR/xmlschema11-2/">[XML Schema 1.1 Part 2:
        ///                                         Datatypes]</a> and <a href = "http://www.iso.ch/markete/8601.pdf">[ISO
        ///                                                              8601]</a> for details. The date/time string format must include a time
        ///  zone, either a Z to indicate Coordinated Universal Time or a + or -
        ///  followed by the difference between the difference from UTC represented as
        ///  hh:mm.
        ///</summary>
        public virtual string GetXSDate(DateTime date, IDateWithLocation cal)
        {
            string xsdDateFormat = "yyyy-MM-dd'T'HH:mm:ss";
            //
            //		 * if (xmlDateFormat == null || xmlDateFormat.trim().equals("")) {
            //		 * xmlDateFormat = xsdDateFormat; }
            //
            //var dateFormat = new SimpleDateFormat(xsdDateFormat);

            var buff = new StringBuilder(date.ToString(xsdDateFormat));
            // Must also include offset from UTF.
            // Get the offset (in milliseconds).
            int offset = cal.Location.TimeZone.UtcOffset(cal.Date);
            // If there is no offset, we have "Coordinated
            // Universal Time."
            if (offset == 0)
                buff.Append("Z");
            else
            {
                // Convert milliseconds to hours and minutes
                int hrs = offset / (60 * 60 * 1000);
                // In a few cases, the time zone may be +/-hh:30.
                int min = offset % (60 * 60 * 1000);
                char posneg = hrs < 0 ? '-' : '+';
                buff.Append(posneg + FormatDigits(hrs) + ':' + FormatDigits(min));
            }
            return buff.ToString();
        }
예제 #25
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ComplexZmanimCalendar"/> class.
 /// </summary>
 /// <param name="dateWithLocation">The date with location.</param>
 public ComplexZmanimCalendar(IDateWithLocation dateWithLocation)
     : base(dateWithLocation)
 {
 }
예제 #26
0
 /// <summary>
 /// A method that calculates UTC sunset as well as any time based on an angle
 /// above or below sunset. This abstract method is implemented by the classes
 /// that extend this class.
 /// </summary>
 /// <param name="astronomicalCalendar">Used to calculate day of year.</param>
 /// <param name="zenith">the azimuth below the vertical zenith of 90°;. For sunset
 /// typically the <see cref="AstronomicalCalculator.AdjustZenith">zenith</see> used for the
 /// calculation uses geometric zenith of 90°; and
 /// <see cref="AstronomicalCalculator.AdjustZenith">adjusts</see> this slightly to account for
 /// solar refraction and the sun's radius. Another example would
 /// be <see cref="AstronomicalCalendar.GetEndNauticalTwilight"/> that
 /// passes <see cref="AstronomicalCalendar.NAUTICAL_ZENITH"/> to this
 /// method.</param>
 /// <param name="adjustForElevation">if set to <c>true</c> [adjust for elevation].</param>
 /// <returns>
 /// The UTC time of sunset in 24 hour format. 5:45:00 AM will return
 /// 5.75.0. If an error was encountered in the calculation (expected
 /// behavior for some locations such as near the poles,
 /// <seealso cref="Double.NaN"/> will be returned.
 /// </returns>
 public abstract double GetUtcSunset(IDateWithLocation dateWithLocation, double zenith, bool adjustForElevation);
예제 #27
0
        /// <summary>
        /// A method that calculates UTC sunset as well as any time based on an angle
        /// above or below sunset. This abstract method is implemented by the classes
        /// that extend this class.
        /// </summary>
        /// <param name="astronomicalCalendar">Used to calculate day of year.</param>
        /// <param name="zenith">the azimuth below the vertical zenith of 90°;. For sunset
        /// typically the <see cref="AstronomicalCalculator.AdjustZenith">zenith</see> used for the
        /// calculation uses geometric zenith of 90°; and
        /// <see cref="AstronomicalCalculator.AdjustZenith">adjusts</see> this slightly to account for
        /// solar refraction and the sun's radius. Another example would
        /// be <see cref="AstronomicalCalendar.GetEndNauticalTwilight"/> that
        /// passes <see cref="AstronomicalCalendar.NAUTICAL_ZENITH"/> to this
        /// method.</param>
        /// <param name="adjustForElevation"></param>
        /// <returns>
        /// The UTC time of sunset in 24 hour format. 5:45:00 AM will return
        /// 5.75.0. If an error was encountered in the calculation (expected
        /// behavior for some locations such as near the poles,
        /// <seealso cref="Double.NaN"/> will be returned.
        /// </returns>
        public override double GetUtcSunset(IDateWithLocation dateWithLocation, double zenith,
                                            bool adjustForElevation)
        {
            // zenith = adjustZenithForElevation(astronomicalCalendar, zenith,
            // geoLocation.getElevation());
            // double elevationAdjustment = this.getElevationAdjustment(zenith,
            // geoLocation.getElevation());
            // double refractionAdjustment = this.getRefraction(zenith);
            // zenith = zenith + elevationAdjustment + refractionAdjustment;

            if (adjustForElevation)
            {
                zenith = AdjustZenith(zenith, dateWithLocation.Location.Elevation);
            }
            else
            {
                zenith = AdjustZenith(zenith, 0);
            }

            // step 1: First calculate the day of the year
            // int calendarDayOfYear = calelendar.DAY_OF_YEAR;

            // int N=theday - date(1,1,theday.year()) + 1;
            int N = dateWithLocation.Date.DayOfYear;

            // step 2: convert the longitude to hour value and calculate an
            // approximate time
            double lngHour = dateWithLocation.Location.Longitude / 15;

            double t = N + ((18 - lngHour) / 24);

            // step 3: calculate the sun's mean anomaly
            double M = (0.9856 * t) - 3.289;

            // step 4: calculate the sun's true longitude
            double L = M + (1.916 * Math.Sin(MathExtensions.ToRadians(M))) + (0.020 * Math.Sin(MathExtensions.ToRadians(2 * M))) +
                       282.634;

            while (L < 0)
            {
                double Lx = L + 360;
                L = Lx;
            }
            while (L >= 360)
            {
                double Lx = L - 360;
                L = Lx;
            }

            // step 5a: calculate the sun's right ascension
            double RA = MathExtensions.ToDegree(Math.Atan(0.91764 * Math.Tan(MathExtensions.ToRadians(L))));

            while (RA < 0)
            {
                double RAx = RA + 360;
                RA = RAx;
            }
            while (RA >= 360)
            {
                double RAx = RA - 360;
                RA = RAx;
            }

            // step 5b: right ascension value needs to be in the same quadrant as L
            double Lquadrant  = Math.Floor(L / 90) * 90;
            double RAquadrant = Math.Floor(RA / 90) * 90;

            RA = RA + (Lquadrant - RAquadrant);

            // step 5c: right ascension value needs to be converted into hours
            RA /= 15;

            // step 6: calculate the sun's declination
            double sinDec = 0.39782 * Math.Sin(MathExtensions.ToRadians(L));
            double cosDec = Math.Cos(Math.Asin(sinDec));

            // step 7a: calculate the sun's local hour angle
            double cosH = (Math.Cos(MathExtensions.ToRadians(zenith)) -
                           (sinDec * Math.Sin(MathExtensions.ToRadians(dateWithLocation.Location.Latitude)))) /
                          (cosDec * Math.Cos(MathExtensions.ToRadians(dateWithLocation.Location.Latitude)));

            // the following line would throw an Exception if the sun never set.
            // this is not needed since the calculation will return a Double.NaN
            // if (cosH < -1) throw new ZmanimException("doesnthappen");

            // step 7b: finish calculating H and convert into hours
            double H = MathExtensions.ToDegree(Math.Acos(cosH));

            H = H / 15;

            // step 8: calculate local mean time

            double T = H + RA - (0.06571 * t) - 6.622;

            // step 9: convert to UTC
            double UT = T - lngHour;

            while (UT < 0)
            {
                double UTx = UT + 24;
                UT = UTx;
            }
            while (UT >= 24)
            {
                double UTx = UT - 24;
                UT = UTx;
            }
            return(UT);
        }
예제 #28
0
        /// <summary>
        /// A method that calculates UTC sunrise as well as any time based on an
        /// angle above or below sunrise. This abstract method is implemented by the
        /// classes that extend this class.
        /// </summary>
        /// <param name="astronomicalCalendar">Used to calculate day of year.</param>
        /// <param name="zenith">the azimuth below the vertical zenith of 90 degrees. for
        /// sunrise typically the <see cref="AstronomicalCalculator.AdjustZenith">zenith</see> used for
        /// the calculation uses geometric zenith of 90°; and
        /// <see cref="AstronomicalCalculator.AdjustZenith">adjusts</see> this slightly to account for
        /// solar refraction and the sun's radius. Another example would
        /// be <see cref="AstronomicalCalendar.GetBeginNauticalTwilight"/>
        /// that passes <see cref="AstronomicalCalendar.NAUTICAL_ZENITH"/> to
        /// this method.</param>
        /// <param name="adjustForElevation"></param>
        /// <returns>
        /// The UTC time of sunrise in 24 hour format. 5:45:00 AM will return
        /// 5.75.0. If an error was encountered in the calculation (expected
        /// behavior for some locations such as near the poles,
        /// <see cref="Double.NaN"/> will be returned.
        /// </returns>
        public override double GetUtcSunrise(IDateWithLocation dateWithLocation, double zenith,
                                             bool adjustForElevation)
        {
            // zenith = adjustZenithForElevation(astronomicalCalendar, zenith,
            // geoLocation.getElevation());
            // double elevationAdjustment = this.getElevationAdjustment(zenith,
            // geoLocation.getElevation());
            // double refractionAdjustment = this.getRefraction(zenith);
            // zenith = zenith + elevationAdjustment + refractionAdjustment;
            if (adjustForElevation)
            {
                zenith = AdjustZenith(zenith, dateWithLocation.Location.Elevation);
            }
            else
            {
                zenith = AdjustZenith(zenith, 0);
            }


            // step 1: First calculate the day of the year
            // NOT NEEDED in this implementation

            // step 2: convert the longitude to hour value and calculate an
            // approximate time
            double lngHour = dateWithLocation.Location.Longitude / 15;

            double t = dateWithLocation.Date.DayOfYear + ((6 - lngHour) / 24); // use 18 for
            // sunset instead
            // of 6

            // step 3: calculate the sun's mean anomaly
            double m = (0.9856 * t) - 3.289;

            // step 4: calculate the sun's true longitude
            double l = m + (1.916 * Math.Sin(MathExtensions.ToRadians(m))) + (0.020 * Math.Sin(MathExtensions.ToRadians(2 * m))) +
                       282.634;

            while (l < 0)
            {
                double Lx = l + 360;
                l = Lx;
            }
            while (l >= 360)
            {
                double Lx = l - 360;
                l = Lx;
            }

            // step 5a: calculate the sun's right ascension
            double RA = MathExtensions.ToDegree(Math.Atan(0.91764 * Math.Tan(MathExtensions.ToRadians(l))));

            while (RA < 0)
            {
                double RAx = RA + 360;
                RA = RAx;
            }
            while (RA >= 360)
            {
                double RAx = RA - 360;
                RA = RAx;
            }

            // step 5b: right ascension value needs to be in the same quadrant as L
            double lQuadrant  = Math.Floor(l / 90) * 90;
            double raQuadrant = Math.Floor(RA / 90) * 90;

            RA = RA + (lQuadrant - raQuadrant);

            // step 5c: right ascension value needs to be converted into hours
            RA /= 15;

            // step 6: calculate the sun's declination
            double sinDec = 0.39782 * Math.Sin(MathExtensions.ToRadians(l));
            double cosDec = Math.Cos(Math.Asin(sinDec));

            // step 7a: calculate the sun's local hour angle
            double cosH = (Math.Cos(MathExtensions.ToRadians(zenith)) -
                           (sinDec * Math.Sin(MathExtensions.ToRadians(dateWithLocation.Location.Latitude)))) /
                          (cosDec * Math.Cos(MathExtensions.ToRadians(dateWithLocation.Location.Latitude)));

            // the following line would throw an Exception if the sun never rose.
            // this is not needed since the calculation will return a Double.NaN
            // if (cosH > 1) throw new Exception("doesnthappen");

            // FOR SUNSET use the following instead of the above if statement.
            // if (cosH < -1)

            // step 7b: finish calculating H and convert into hours
            double H = 360 - MathExtensions.ToDegree(Math.Acos(cosH));

            // FOR SUNSET remove "360 - " from the above

            H = H / 15;

            // step 8: calculate local mean time

            double T = H + RA - (0.06571 * t) - 6.622;

            // step 9: convert to UTC
            double UT = T - lngHour;

            while (UT < 0)
            {
                double UTx = UT + 24;
                UT = UTx;
            }
            while (UT >= 24)
            {
                double UTx = UT - 24;
                UT = UTx;
            }
            return(UT);
        }
예제 #29
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ZmanimCalendar"/> class.
 /// </summary>
 /// <param name="dateWithLocation">The date with location.</param>
 public ZmanimCalendar(IDateWithLocation dateWithLocation)
     : base(dateWithLocation)
 {
 }
예제 #30
0
 /// <summary>
 /// A method that calculates UTC sunset as well as any time based on an angle
 /// above or below sunset. This abstract method is implemented by the classes
 /// that extend this class.
 /// </summary>
 /// <param name="dateWithLocation">Used to calculate day of year.</param>
 /// <param name="zenith">the azimuth below the vertical zenith of 90°;. For sunset
 /// typically the <see cref="AstronomicalCalculator.AdjustZenith">zenith</see> used for the
 /// calculation uses geometric zenith of 90°; and
 /// <see cref="AstronomicalCalculator.AdjustZenith">adjusts</see> this slightly to account for
 /// solar refraction and the sun's radius. Another example would
 /// be <see cref="AstronomicalCalendar.GetEndNauticalTwilight"/> that
 /// passes <see cref="AstronomicalCalendar.NAUTICAL_ZENITH"/> to this
 /// method.</param>
 /// <param name="adjustForElevation"></param>
 /// <returns>
 /// The UTC time of sunset in 24 hour format. 5:45:00 AM will return
 /// 5.75.0. If an error was encountered in the calculation (expected
 /// behavior for some locations such as near the poles,
 /// <seealso cref="Double.NaN"/> will be returned.
 /// </returns>
 public override double GetUtcSunset(
     IDateWithLocation dateWithLocation, double zenith, bool adjustForElevation)
 {
     return(GetUtcSunriseSunset(dateWithLocation, zenith, adjustForElevation, false));
 }
예제 #31
0
        ///<summary>
        ///  Generate a Julian day from Java Calendar
        ///</summary>
        ///<param name = "date">
        ///  Java Calendar </param>
        ///<returns> the Julian day corresponding to the date Note: Number is returned
        ///  for start of day. Fractional days should be added later. </returns>
        private static double CalcJd(IDateWithLocation date)
        {
            int year = date.Date.Year;
            int month = date.Date.Month + 1;
            int day = date.Date.Day;
            if (month <= 2)
            {
                year -= 1;
                month += 12;
            }
            double A = Math.Floor((double)(year / 100));
            double B = 2 - A + Math.Floor(A / 4);

            return Math.Floor(365.25 * (year + 4716)) + Math.Floor(30.6001 * (month + 1)) + day + B - 1524.5;
        }
예제 #32
0
        /// <summary>
        /// A method that calculates UTC sunset as well as any time based on an angle
        /// above or below sunset. This abstract method is implemented by the classes
        /// that extend this class.
        /// </summary>
        /// <param name="astronomicalCalendar">Used to calculate day of year.</param>
        /// <param name="zenith">the azimuth below the vertical zenith of 90°;. For sunset
        /// typically the <see cref="AstronomicalCalculator.AdjustZenith">zenith</see> used for the
        /// calculation uses geometric zenith of 90°; and
        /// <see cref="AstronomicalCalculator.AdjustZenith">adjusts</see> this slightly to account for
        /// solar refraction and the sun's radius. Another example would
        /// be <see cref="AstronomicalCalendar.GetEndNauticalTwilight"/> that
        /// passes <see cref="AstronomicalCalendar.NAUTICAL_ZENITH"/> to this
        /// method.</param>
        /// <param name="adjustForElevation"></param>
        /// <returns>
        /// The UTC time of sunset in 24 hour format. 5:45:00 AM will return
        /// 5.75.0. If an error was encountered in the calculation (expected
        /// behavior for some locations such as near the poles,
        /// <seealso cref="Double.NaN"/> will be returned.
        /// </returns>
        public override double GetUtcSunset(IDateWithLocation dateWithLocation, double zenith,
                                            bool adjustForElevation)
        {
            // zenith = adjustZenithForElevation(astronomicalCalendar, zenith,
            // geoLocation.getElevation());
            // double elevationAdjustment = this.getElevationAdjustment(zenith,
            // geoLocation.getElevation());
            // double refractionAdjustment = this.getRefraction(zenith);
            // zenith = zenith + elevationAdjustment + refractionAdjustment;

            if (adjustForElevation)
            {
                zenith = AdjustZenith(zenith, dateWithLocation.Location.Elevation);
            }
            else
            {
                zenith = AdjustZenith(zenith, 0);
            }

            // step 1: First calculate the day of the year
            // int calendarDayOfYear = calelendar.DAY_OF_YEAR;

            // int N=theday - date(1,1,theday.year()) + 1;
            int N = dateWithLocation.Date.DayOfYear;

            // step 2: convert the longitude to hour value and calculate an
            // approximate time
            double lngHour = dateWithLocation.Location.Longitude / 15;

            double t = N + ((18 - lngHour)/24);

            // step 3: calculate the sun's mean anomaly
            double M = (0.9856*t) - 3.289;

            // step 4: calculate the sun's true longitude
            double L = M + (1.916*Math.Sin(MathExtensions.ToRadians(M))) + (0.020*Math.Sin(MathExtensions.ToRadians(2*M))) +
                       282.634;
            while (L < 0)
            {
                double Lx = L + 360;
                L = Lx;
            }
            while (L >= 360)
            {
                double Lx = L - 360;
                L = Lx;
            }

            // step 5a: calculate the sun's right ascension
            double RA = MathExtensions.ToDegree(Math.Atan(0.91764*Math.Tan(MathExtensions.ToRadians(L))));
            while (RA < 0)
            {
                double RAx = RA + 360;
                RA = RAx;
            }
            while (RA >= 360)
            {
                double RAx = RA - 360;
                RA = RAx;
            }

            // step 5b: right ascension value needs to be in the same quadrant as L
            double Lquadrant = Math.Floor(L/90)*90;
            double RAquadrant = Math.Floor(RA/90)*90;
            RA = RA + (Lquadrant - RAquadrant);

            // step 5c: right ascension value needs to be converted into hours
            RA /= 15;

            // step 6: calculate the sun's declination
            double sinDec = 0.39782*Math.Sin(MathExtensions.ToRadians(L));
            double cosDec = Math.Cos(Math.Asin(sinDec));

            // step 7a: calculate the sun's local hour angle
            double cosH = (Math.Cos(MathExtensions.ToRadians(zenith)) -
                           (sinDec * Math.Sin(MathExtensions.ToRadians(dateWithLocation.Location.Latitude)))) /
                          (cosDec * Math.Cos(MathExtensions.ToRadians(dateWithLocation.Location.Latitude)));

            // the following line would throw an Exception if the sun never set.
            // this is not needed since the calculation will return a Double.NaN
            // if (cosH < -1) throw new ZmanimException("doesnthappen");

            // step 7b: finish calculating H and convert into hours
            double H = MathExtensions.ToDegree(Math.Acos(cosH));
            H = H/15;

            // step 8: calculate local mean time

            double T = H + RA - (0.06571*t) - 6.622;

            // step 9: convert to UTC
            double UT = T - lngHour;
            while (UT < 0)
            {
                double UTx = UT + 24;
                UT = UTx;
            }
            while (UT >= 24)
            {
                double UTx = UT - 24;
                UT = UTx;
            }
            return UT;
        }