sunrise sunset times in c

2020-05-28 17:57发布

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.

标签: c time
11条回答
beautiful°
2楼-- · 2020-05-28 18:30

This is adaptable and is quite accurate. You'll get all the components and then all you need to calculate is the arc cosine for the Zenith to Horizon angle. Yes there are simpler ways but don't you basically want to track the Sun? It could come in handy some day. http://www.nrel.gov/midc/spa/

查看更多
smile是对你的礼貌
3楼-- · 2020-05-28 18:31

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

查看更多
贪生不怕死
4楼-- · 2020-05-28 18:32

Pure C implementations are apparently scarce but if You are willing to port either from C++ or C# then there are a couple of options:

  1. C++ Sunrise/Sunset Calculations
  2. C# Get sunrise and sunset time based on latitude and longitude
查看更多
男人必须洒脱
5楼-- · 2020-05-28 18:36
别忘想泡老子
6楼-- · 2020-05-28 18:36

There is a c solution with an objective c wrapper for sunrise/set here: https://github.com/berkley/ObjectiveCUtil

查看更多
啃猪蹄的小仙女
7楼-- · 2020-05-28 18:37

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);
    }
查看更多
登录 后发表回答