none
Get sunrise and sunset time based on latitude and longitude

    Question

  • Hi. I've tried my best to find a correct forum for where I can post about the location-specific/time question, but here goes:

     

    Home Automation software, like ActiveHome Pro and Insteon Timer Software (scroll down) have an ability to let me select a longitude/latitude (or city/state) based on sunrise and sunset time, so I wanted to implement this when developing my own home automation application.

     

    Once I know my longitude and latitude (www.maporama.com is where I went there to find my longitude and latitude for my home address), how do I go about known when a sunrise and sunset occour at a certain time? I do believe that home automation applications don't connect to the Internet to get the times for sunrise/sunset for every day, as it doesn't use the Internet...

    Sunday, July 15, 2007 7:43 PM

Answers

All replies

  • If you're prepared to deal with the math involved, see http://www.srrb.noaa.gov/highlights/sunrise/calcdetails.html.  Otherwise there may be web services you could query for the data you want.
    Sunday, July 15, 2007 7:53 PM
  • You could also try looking at this project in C++, but it also mentions the same source as Peter (NOAA);

     

    http://www.codeproject.com/datetime/srss.asp

    Sunday, July 15, 2007 8:58 PM
  • I can handle math once I study more since I've completed beginning algebra in college of first semester of this year.

     

    Thanks.

    Monday, July 16, 2007 2:36 AM
  • Boy I got a lot of clean-up to do, but I'll give myself a rest until today (it's after midnight).

     

    In the meantime, here's my converted code (note that I omitted one function off since I don't care for DD-MONTH format but went with mm/dd/yyyy):

     

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Text;

     

    namespace GraysonPeddie.HomeAutomation.Network.Server

    {

        public static class SolarPositionCalculator

        {

            public static double ConvertFromRadianToDegrees ( double angleRadian )

            {

                return ( 180.0 * angleRadian / Math.PI );

            }

     

            public static double ConvertFromDegreesToRadian ( double angleDegrees )

            {

                return ( Math.PI * angleDegrees / 180.0 );

            }

     

            /// <summary>

            /// Finds numerical day-of-year from month, day,

            /// and leap year information.

            /// </summary>

            /// <param name="month">Month of year</param>

            /// <param name="day">Day of month</param>

            /// <param name="isLeapYear">Is the year a leap year?</param>

            /// <returns>The numerical day of year</returns>

            public static double CalculateDayOfYear

                ( int month , int day , bool isLeapYear )

            {

                int leapYear = isLeapYear ? 1 : 2;

                return ( Math.Floor ( ( ( 275.0 * month ) / 9.0 ) - leapYear ) *

                    Math.Floor ( ( ( month + 9.0 ) / 12.0 ) + day - 30 ) );

            }

     

            /// <summary>

            /// Derives weekday from Julian Day

            /// </summary>

            /// <param name="julianDay">Julian Day</param>

            /// <returns>String containing name of weekday</returns>

            public static string CalculateDayOfWeek ( double julianDay )

            {

                double day = ( julianDay + 1.5 ) % 7;

                return

                    ( day == 0 ) ?  "Sunday" :

                    ( day == 1 ) ?  "Monday" :

                    ( day == 2 ) ?  "Tuesday" :

                    ( day == 3 ) ?  "Wednesday" :

                    ( day == 4 ) ?  "Thursday" :

                    ( day == 5 ) ?  "Friday" :

                                    "Saturday";

            }

     

            /// <summary>

            /// Julian Day from calender day

            /// </summary>

            /// <param name="year">Four-Digit Year</param>

            /// <param name="month">Month of year</param>

            /// <param name="day">Day of month</param>

            /// <returns>The Julian day corresponding to the date</returns>

            /// <remarks>Number is returned for start of day.

            /// Fractional days should be added later.</remarks>

            public static double CalculateJulianDay ( int year , int month , int day )

            {

                int _year = year , _month = month;

                // Is it January or February?

                if ( month <= 2 )

                {

                    _year = year - 1;

                    _month = month + 12;

                }

     

                double a = Math.Floor ( _year / 100.0 );

                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 );

            }

     

            /// <summary>

            /// Calculate calender date from Julian Day.

            /// </summary>

            /// <param name="julianDay">Julian Day</param>

            /// <returns>String date in form mm/dd/yyyy</returns>

            public static string CalculateDateFromJulianDay ( double julianDay )

            {

                double z = Math.Floor ( julianDay + 0.5 );

                double f = ( julianDay + 0.5 ) - z;

     

                double a, alpha;

                if ( z < 2299161 )

                {

                    a = z;

                }

                else

                {

                    alpha = Math.Floor ( ( z - 1867216.25 ) / 36524.25 );

                    a = z + 1 + alpha - Math.Floor ( alpha / 4 );

                }

     

                double b = a + 1524;

                double c = Math.Floor ( ( b - 122.1 ) / 365.25 );

                double d = Math.Floor ( 365.25 * c );

                double e = Math.Floor ( ( b - d ) / 30.6001 );

               

                double day =

                    b - d - Math.Floor ( 30.6001 * e ) + f;

                double month = ( e < 14 ) ? e - 1 : e - 14;

                double year =

                    ( month > 2 ) ? c - 4716 : c - 4715;

     

                return

                    month.ToString ( ) + "/" +

                    day.ToString ( ) + "/" +

                    year.ToString ( );

            }

     

            /// <summary>

            /// Calculate time of Julian Century

            /// </summary>

            /// <param name="julianDay">Julian Day</param>

            /// <returns>A Julian Century corresponding to the Julian Day</returns>

            public static double CalculateTimeOfJulianCentury (

                double julianDay )

            {

                return ( julianDay - 2451545.0 ) / 36525.0;

            }

     

            /// <summary>

            /// Convert centuries since January 2000 to Julian Day.

            /// </summary>

            /// <param name="time">Number of Julian Centuries since

            /// January 2000</param>

            /// <returns>the Julian Day corresponding to a Julian Century

            /// </returns>

            public static double CalculateJulianDayFromTimeOfJulianCentury (

                double time )

            {

                return time * 36525.0 + 2451545.0;

            }

     

            /// <summary>

            /// calculate the Geometric Mean Longitude of the Sun

            /// </summary>

            /// <param name="time">number of Julian centuries since

            /// Janruary 2000</param>

            /// <returns>the Geometric Mean Longitude of the Sun in degrees</returns>

            public static double CalculateGeometricMeanLongitudeOfSunInDegrees (

                double time )

            {

                double longitude =

                    280.46646 + time * ( 36000.76983 + 0.0003032 * time );

                while ( longitude > 360.0 ) longitude -= 360.0;

                while ( longitude < 360.0 ) longitude += 360.0;

                return longitude; // in degrees

            }

     

            /// <summary>

            /// Calculate the Geometric Mean Anomaly of the Sun

            /// </summary>

            /// <param name="time">number of Julian centuries since

            /// January 2000</param>

            /// <returns>the Geometric Mean Anomaly of the Sun in degrees

            /// </returns>

            public static double CalculateGeometricMeanAnomalyOfSunInDegrees (

                double time )

            {

                return 357.52911 + time * ( 35999.05029 - 0.0001537 * time );

            }

     

            /// <summary>

            /// calculate the eccentricity of earth's orbit

            /// </summary>

            /// <param name="time">number of Julian centuries since

            /// January 2000</param>

            /// <returns>the unitless eccentricity</returns>

            public static double CalculateEccentricityOfEarthOrbit ( double time )

            {

                return 0.016708634 - time * ( 0.000042037 + 0.0000001267 * time );

            }

     

            /// <summary>

            /// Calculate the equation of center for the sun.

            /// </summary>

            /// <param name="time">number of Julian centuries since

            /// January 2000</param>

            /// <returns>in degrees</returns>

            public static double CalculateEquationOfCenterForSun ( double time )

            {

                double m = CalculateGeometricMeanAnomalyOfSunInDegrees ( time );

     

                double mRadian = ConvertFromDegreesToRadian ( m );

                double mSine = Math.Sin ( mRadian );

                double mSine2 = Math.Sin ( mRadian * 2 );

                double mSine3 = Math.Sin ( mRadian * 3 );

     

                return

                    mSine * ( 1.914602 - time * ( 0.004817 + 0.000014 * time ) ) +

                    mSine2 * ( 0.019993 - 0.000101 * time ) +

                    mSine3 * 0.000289;

            }

     

            /// <summary>

            /// calculate the true longitude of the sun

            /// </summary>

            /// <param name="time">number of Julian centuries since

            /// January 2000</param>

            /// <returns>Sun's true longitude in degrees</returns>

            public static double CalculateTrueLongitudeOfSun ( double time )

            {

                double longitude =

                    CalculateGeometricMeanAnomalyOfSunInDegrees ( time );

                double center =

                    CalculateEquationOfCenterForSun ( time );

     

                return longitude + center;

            }

     

            /// <summary>

            /// Calculate the true anamoly of the sun

            /// </summary>

            /// <param name="time">number of Julian centuries since

            /// January 2000</param>

            /// <returns>Sun's true anamoly in degrees</returns>

            public static double CalculateTrueAnomalyFromTheSun ( double time )

            {

                double anomaly =

                    CalculateGeometricMeanAnomalyOfSunInDegrees ( time );

                double center =

                    CalculateEquationOfCenterForSun ( time );

     

                return anomaly + center;

            }

     

            /// <summary>

            /// Calculate the distance to the sun in AU

            /// </summary>

            /// <param name="time">number of Julian centuries since

            /// January 2000</param>

            /// <returns>Sun radius vector in AUs</returns>

            public static double CalculateDistanceToSunInAU ( double time )

            {

                double vector =

                    CalculateTrueAnomalyFromTheSun ( time );

                double eccentricity =

                    CalculateEccentricityOfEarthOrbit ( time );

     

                return

                    ( 1.000001018 * ( 1 - eccentricity * eccentricity ) ) /

                    ( 1 + eccentricity * Math.Cos (

                    ConvertFromDegreesToRadian ( vector ) ) );

            }

     

            /// <summary>

            /// Calculate the apparent longitude of the sun

            /// </summary>

            /// <param name="time">number of Julian centuries since

            /// January 2000</param>

            /// <returns>Sun's apparent longitude in degrees</returns>

            public static double CalculateSunApparentLongitude ( double time )

            {

                double o = CalculateTrueLongitudeOfSun ( time );

     

                double omega = 125.04 - 1934.136 * time;

                // returns lambda

                return o - 0.00569 - 0.00478 *

                    Math.Sin ( ConvertFromDegreesToRadian ( omega ) );

            }

     

            /// <summary>

            /// Calculate the mean obliquity of the ecliptic

            /// </summary>

            /// <param name="time">number of Julian centuries since

            /// January 2000</param>

            /// <returns>Mean obliquity in degrees</returns>

            public static double CalculateMeanObliquityOfEcliptic ( double time )

            {

                double seconds =

                    21.448 - time * (

                    46.8150 + time * (

                    0.00059 + time * (

                    0.001813 ) ) );

     

                return 23.0 + ( 26.0 + ( seconds / 60.0 ) ) / 60.0;

            }

     

            /// <summary>

            /// Calculate the corrected obliquity of the ecliptic

            /// </summary>

            /// <param name="time">number of Julian centuries since

            /// January 2000</param>

            /// <returns>Corrected obliquity in degrees</returns>

            public static double CalculateCorrectedObliquityOfEcliptic ( double time )

            {

                double ecliptic = CalculateMeanObliquityOfEcliptic ( time );

     

                double omega = 125.04 - 1934.136 * time;

                return ecliptic + 0.00256 *

                    Math.Cos ( ConvertFromDegreesToRadian ( omega ) );

            }

     

            /// <summary>

            /// Calculate the right ascension of the sun

            /// </summary>

            /// <param name="time">number of Julian centuries since

            /// January 2000</param>

            /// <returns>Sun's right ascension in degrees</returns>

            public static double CalculateRightAscensionOfSun ( double time )

            {

                double ecliptic = CalculateCorrectedObliquityOfEcliptic ( time );

                double lambda = CalculateSunApparentLongitude ( time );

     

                double tanaNum = (

                    Math.Cos ( ConvertFromDegreesToRadian ( ecliptic ) ) *

                    Math.Sin ( ConvertFromDegreesToRadian ( lambda ) ) );

                double tanaDenom = (

                    Math.Cos ( ConvertFromDegreesToRadian ( lambda ) ) );

     

                return ConvertFromRadianToDegrees ( Math.Atan2 (

                    tanaNum , tanaDenom ) );

            }

     

            /// <summary>

            /// Calculate the declination of the sun

            /// </summary>

            /// <param name="time">number of Julian centuries since

            /// January 2000</param>

            /// <returns>Sun's declination in degrees</returns>

            public static double CalculateDeclinationOfSun ( double time )

            {

                double ecliptic = CalculateCorrectedObliquityOfEcliptic ( time );

                double lambda = CalculateSunApparentLongitude ( time );

     

                double sineT =

                    Math.Sin ( ConvertFromDegreesToRadian ( ecliptic ) ) *

                    Math.Sin ( ConvertFromDegreesToRadian ( lambda ) );

                // theta

                return ConvertFromRadianToDegrees ( Math.Asin ( sineT ) );

            }

     

            /// <summary>

            /// Calculate the difference between:

            ///     true solar time and

            ///     mean solar time

            /// </summary>

            /// <param name="time">number of Julian centuries since

            /// January 2000</param>

            /// <returns>Equation of time in minutes of time</returns>

            public static double CalculateDifferenceTimeAndMeanSolarTime ( double time )

            {

                double epsilon = CalculateCorrectedObliquityOfEcliptic ( time );

                double longitude =

                    CalculateGeometricMeanLongitudeOfSunInDegrees ( time );

                double ecliptic = CalculateEccentricityOfEarthOrbit ( time );

                double anomaly =

                    CalculateGeometricMeanAnomalyOfSunInDegrees ( time );

     

                double year =

                    Math.Tan ( ConvertFromDegreesToRadian ( epsilon ) / 2.0 );

                year *= year;

     

                double Sine2Longitude =

                    Math.Sin ( 2.0 * ConvertFromDegreesToRadian ( longitude ) );

                double Sine1Anomality =

                    Math.Sin ( 1.0 * ConvertFromDegreesToRadian ( anomaly ) );

                double Cosine2Longitude =

                    Math.Cos ( 2.0 * ConvertFromDegreesToRadian ( longitude ) );

                double Sine4Longitude =

                    Math.Sin ( 4.0 * ConvertFromDegreesToRadian ( longitude ) );

                double Sine2Anomality =

                    Math.Sin ( 2.0 * ConvertFromDegreesToRadian ( anomaly ) );

     

                double eclipticTime =

                    year * Sine2Longitude - 2.0 * ecliptic * Sine1Anomality + 4.0 *

                    ecliptic * year * Sine1Anomality * Cosine2Longitude - 0.5 *

                    year * year * Sine4Longitude - 1.25 * ecliptic * ecliptic *

                    Sine2Anomality;

     

                // in minutes of time

                return ConvertFromRadianToDegrees ( eclipticTime ) * 4.0;

            }

        }

    }

     

    There are a lot of functions that confuse me, even though I've done my best to document the functions, but I've never heard of Julian Day, and I don't know where to start off with on how to gather a sunrise and sunset time, other than just having to input a day, month, and year...

     

    Well, my research starts today... Smile

     

    The reason why not to choose a web service (even though my home automation server connects to the Internet) is I plan to develop a home automation software where there are scenarios when a home owner doesn't want a computer to be connected to the Internet but instead, serve as a home automation server for controlling lights.

    Monday, July 16, 2007 6:33 AM