sunrise sunset times in c

23,530

Solution 1

The sample code appears to work in VC++ 2010 with a few minor changes:

  • Compile it as a C++ file and not C.
  • Remove the #include <sys/time.h> line.
  • Add a #define _USE_MATH_DEFINES at the top of the file in order for M_PI to be defined.
  • Change the two %T in the strftime() calls to %X.

Now that you have a working sample you can debug the working version and your version to see where the calculation begins to differ and narrow in on the issue. Either step through the program or make liberal use of temporary printf() calls much like the sample does.

If you want specific help you will have to post your code (either a link to the entire file or particular snippets you need help with).

Solution 2

Ten simple steps to follow to calculate sunrise / sunset time given the date, latitude and longitude

  1. first calculate the day of the year

    N1 = floor(275 * month / 9) N2 = floor((month + 9) / 12) N3 = (1 + floor((year - 4 * floor(year / 4) + 2) / 3)) N = N1 - (N2 * N3) + day - 30

  2. convert the longitude to hour value and calculate an approximate time

    lngHour = longitude / 15

    if rising time is desired: t = N + ((6 - lngHour) / 24) if setting time is desired: t = N + ((18 - lngHour) / 24)

  3. calculate the Sun's mean anomaly

    M = (0.9856 * t) - 3.289

  4. calculate the Sun's true longitude

    L = M + (1.916 * sin(M)) + (0.020 * sin(2 * M)) + 282.634 NOTE: L potentially needs to be adjusted into the range [0,360) by adding/subtracting 360

5a. calculate the Sun's right ascension

RA = atan(0.91764 * tan(L))
NOTE: RA potentially needs to be adjusted into the range [0,360) by adding/subtracting 360

5b. right ascension value needs to be in the same quadrant as L

Lquadrant  = (floor( L/90)) * 90
RAquadrant = (floor(RA/90)) * 90
RA = RA + (Lquadrant - RAquadrant)

5c. right ascension value needs to be converted into hours

RA = RA / 15
  1. calculate the Sun's declination

    sinDec = 0.39782 * sin(L) cosDec = cos(asin(sinDec))

7a. calculate the Sun's local hour angle

cosH = (cos(zenith) - (sinDec * sin(latitude))) / (cosDec * cos(latitude))

if (cosH >  1) 
  the sun never rises on this location (on the specified date)
if (cosH < -1)
  the sun never sets on this location (on the specified date)

7b. finish calculating H and convert into hours

if if rising time is desired:
  H = 360 - acos(cosH)
if setting time is desired:
  H = acos(cosH)

H = H / 15
  1. calculate local mean time of rising/setting

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

  2. adjust back to UTC

    UT = T - lngHour NOTE: UT potentially needs to be adjusted into the range [0,24) by adding/subtracting 24

  3. convert UT value to local time zone of latitude/longitude

    localT = UT + localOffset

Solution 3

This seems quite easy to implement:
http://edwilliams.org/sunrise_sunset_algorithm.htm

Solution 4

Using this guide (which was first posted by @BenjaminMonate and I assume is the same one @Geetha used), I built this C function which seems to work correctly.

#include <math.h>
#define PI 3.1415926
#define ZENITH -.83

float calculateSunrise(int year,int month,int day,float lat, float lng,int localOffset, int daylightSavings) {
    /*
    localOffset will be <0 for western hemisphere and >0 for eastern hemisphere
    daylightSavings should be 1 if it is in effect during the summer otherwise it should be 0
    */
    //1. first calculate the day of the year
    float N1 = floor(275 * month / 9);
    float N2 = floor((month + 9) / 12);
    float N3 = (1 + floor((year - 4 * floor(year / 4) + 2) / 3));
    float N = N1 - (N2 * N3) + day - 30;

    //2. convert the longitude to hour value and calculate an approximate time
    float lngHour = lng / 15.0;      
    float t = N + ((6 - lngHour) / 24);   //if rising time is desired:
    //float t = N + ((18 - lngHour) / 24)   //if setting time is desired:

    //3. calculate the Sun's mean anomaly   
    float M = (0.9856 * t) - 3.289;

    //4. calculate the Sun's true longitude
    float L = fmod(M + (1.916 * sin((PI/180)*M)) + (0.020 * sin(2 *(PI/180) * M)) + 282.634,360.0);

    //5a. calculate the Sun's right ascension      
    float RA = fmod(180/PI*atan(0.91764 * tan((PI/180)*L)),360.0);

    //5b. right ascension value needs to be in the same quadrant as L   
    float Lquadrant  = floor( L/90) * 90;
    float RAquadrant = floor(RA/90) * 90;
    RA = RA + (Lquadrant - RAquadrant);

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

    //6. calculate the Sun's declination
    float sinDec = 0.39782 * sin((PI/180)*L);
    float cosDec = cos(asin(sinDec));

    //7a. calculate the Sun's local hour angle
    float cosH = (sin((PI/180)*ZENITH) - (sinDec * sin((PI/180)*lat))) / (cosDec * cos((PI/180)*lat));
    /*   
    if (cosH >  1) 
    the sun never rises on this location (on the specified date)
    if (cosH < -1)
    the sun never sets on this location (on the specified date)
    */

    //7b. finish calculating H and convert into hours
    float H = 360 - (180/PI)*acos(cosH);   //   if if rising time is desired:
    //float H = acos(cosH) //   if setting time is desired:      
    H = H / 15;

    //8. calculate local mean time of rising/setting      
    float T = H + RA - (0.06571 * t) - 6.622;

    //9. adjust back to UTC
    float UT = fmod(T - lngHour,24.0);

    //10. convert UT value to local time zone of latitude/longitude
    return UT + localOffset + daylightSavings;

    }

void printSunrise() {
    float localT = calculateSunrise(/*args*/);
    double hours;
    float minutes = modf(localT,&hours)*60;
    printf("%.0f:%.0f",hours,minutes);
    }

Solution 5

code provided by scottmrogowski was useful, two issues however

  1. //float H = (180/PI)*acos(cosH) // if setting time is desired:
  2. float localT=fmod(24 + calculateSunrise(/* args */),24.0); //in printSunrise function

Cheers Marek

Share:
23,530
Fer
Author by

Fer

I am a R&amp;D Engineer, developings different software projects. I used many programming languages such as C#,Java,Android,Asp.Net,C etc.

Updated on July 05, 2022

Comments

  • Fer
    Fer almost 2 years

    In my C application, I want to calculate sunrise/sunset times for a given date, latitude and longitude. i have been searching on the net but i can not find a working sample.

    I tried to implement this sample: http://souptonuts.sourceforge.net/code/sunrise.c.html

    But this sample didnt work correctly.

    Is there a simple C source code or method which i can easly implement in my application?

    Edit:
    I implement the code on this link but it gave me the wrong sunset/sunrise values. Also i tried the Saul's link here but it gave me the wrong result either.
    I have 41N, 28E location. When i try the codes, both sample says that sunrise value is aproximately 10:13 and sunset is 23:24. But the correct values are 06:06, 20:13.
    I can not understand the problem.

  • Fer
    Fer almost 13 years
    I run your C++ sample on first link but the project shows wrong results. Pls read my edit above.
  • Fer
    Fer almost 13 years
    I have already update the sample as you described on your steps. But when i run the code, it gives incorrect sunrise/sunset values. <br> if you can run the sample, can you set the variables year=2011, month=8, day=15, latitude = 28, longitude = 41 and run the code? The correct value pair for sunrise and sunset times must be 04:27, 20:13. But i get 11:13, 00:22. Can you share what you get when you run the code?
  • uesp
    uesp almost 13 years
    I get: Sunrise 08-15-2011 04:17:19 Sunset 08-15-2011 17:16:17. Be aware that the sample appears to take a West latitude and North longitude as positive. This means that you are trying to find the sunrise/set times for (41w, 28n) which is in the middle of the Atlantic Ocean. The sample also computes the times in your local time and not the time at the specified destination.
  • Fer
    Fer almost 13 years
    Hello, thank you for your help. Finally i get it working correctly. As you mentioned, i putted the wrong location information. My actual coordinates should be -29East, +41North. When i enter these variables(with negative sign for east), the computation gives the correct result. Actually it gives aproximately 7/10 minutes difference from my referance times but it is not a problem. That difference must be between sunrising start/finish difference. Thank you.
  • oliverseal
    oliverseal almost 11 years
    Note: on this solution you will need to know the sun's zenith for this location. Humorously, the Wikipedia article on calculating the zenith (en.wikipedia.org/wiki/Solar_zenith_angle) actually requires the local hour angle, which is what this formula uses the zenith to calculate. Still useful calculation -- just needs the zenith as input. Sun's zenith for sunrise/sunset official = 90 degrees 50' civil = 96 degrees nautical = 102 degrees astronomical = 108 degrees
  • Adion
    Adion over 9 years
    The local time variants have a small bug around midnight. Instead of h2-h1, first calculate dif as follows: int dif = h2-h1; if (dif<-12) dif += 24;
  • Rohmer
    Rohmer over 8 years
    I appreciate the math and steps.
  • Chris
    Chris over 2 years
    Welcome to Stack Overflow. Please take the tour and read How to Answer. OP is asking how to do this in C. How does a command-line utility answer the question?