sunrise sunset times in c
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 thestrftime()
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
-
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
-
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)
-
calculate the Sun's mean anomaly
M = (0.9856 * t) - 3.289
-
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
-
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
-
calculate local mean time of rising/setting
T = H + RA - (0.06571 * t) - 6.622
-
adjust back to UTC
UT = T - lngHour NOTE: UT potentially needs to be adjusted into the range [0,24) by adding/subtracting 24
-
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
- //float H = (180/PI)*acos(cosH) // if setting time is desired:
- float localT=fmod(24 + calculateSunrise(/* args */),24.0); //in printSunrise function
Cheers Marek
Fer
I am a R&D Engineer, developings different software projects. I used many programming languages such as C#,Java,Android,Asp.Net,C etc.
Updated on July 05, 2022Comments
-
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 almost 13 yearsI run your C++ sample on first link but the project shows wrong results. Pls read my edit above.
-
Fer almost 13 yearsI 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 almost 13 yearsI 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 almost 13 yearsHello, 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 almost 11 yearsNote: 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 over 9 yearsThe 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 over 8 yearsI appreciate the math and steps.
-
Chris over 2 yearsWelcome 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?