-2

I want to calculate the sunset for specific localization (latitude, longtitude) in C.

I modeled on: http://edwilliams.org/sunrise_sunset_algorithm.htm

For the given model I tried to calculate the sunrise - this value was good. I still get the incorrect value for sunset: -11:-22.

Here's some code:

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

float calculateSunset(int year,int month,int day,float lat, float lng,int localOffset) {

//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;
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) {
    printf("the sun never rises on this location (on the specified date)");
    return 0;
}

if (cosH < -1) {
    printf("the sun never sets on this location (on the specified date)");
    return 0;
}

//7b. finish calculating H and convert into hours
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;

}

void printSunset() {

    float localT = calculateSunset(2018,10,4,51.8446,19.2094,2);
    double hours;
    float minutes = modf(localT,&hours)*60;
    printf("Sunset: ");
    printf("%.0f:%.0f",hours,minutes);   
    printf("\n"); 
}


int main()
{
  printSunset();
  return 0;
}

Could anyone help me? What am I doing wrong?

maghost
  • 39
  • 1
  • 7
  • 1
    What are you doing wrong? You didn't read and follow the instructions on the [How do I ask a good question?](https://stackoverflow.com/help/how-to-ask) page. "Here's some code ... What am I doing wrong?" is expecting people to do a lot of work figuring out what's going on. You should make it easier for people to help you by providing a lot more information. – Andrew Henle Oct 04 '18 at 15:16
  • Also, pay close attention to where *integer division* is occurring. – David C. Rankin Oct 04 '18 at 15:27
  • Always (\*) prefer `double` when dealing with floating-point values. (\*) yes, always! – pmg Oct 04 '18 at 20:08

1 Answers1

1

I think your main problem is that you expect fmod to return a positive result - that is not true, fmod preserves the sign i.e. if you are taking fmod of a negative value you'll get a (correct) negative result, if you use it on an positive value the (also correct) result will be positive. If you require an positive result you could for example simply add the divisor if the result is negative i.e.

float a = fmod(T, 360.0);
if(a < 0) { a = a + 360.0; }
tsp
  • 333
  • 3
  • 7