include stdint include math define tl_hour define tl_minute define tl_

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include <stdint.h>
#include <math.h>
#define tl_hour 0
#define tl_minute 1
#define tl_second 2
#define tl_day 3
#define tl_month 4
#define tl_year 5
// Часы, Минуты, Секунды, Число, Месяц, Год
uint16_t dt[] = {0, 0, 0, 5, 5, 2019};
// Широта и долгота
float latitude=55.708102, longitude=36.794008;
// Часовая зона в минутах (часы * 60)
int timezone=3*60;
uint8_t ComputeSun(uint8_t rs);
int main()
{
ComputeSun(1); // Восход
ComputeSun(0); // Заход
return 0;
}
uint8_t IsLeapYear(int yr){
return ( (yr % 4 == 0 && yr % 100 != 0) || yr % 400 == 0);
}
uint8_t LengthOfMonth(uint16_t * when){
uint8_t odd, mnth;
int yr;
yr=when[tl_year]+2000;
mnth=when[tl_month];
if(mnth==2){
if(IsLeapYear(yr) ) return 29;
return 28;
}
odd=(mnth & 1) == 1;
if (mnth > 7) odd = !odd;
if (odd) return 31;
return 30;
}
int Absolute(int n){
if(n<0) return 0-n;
return n;
}
char Signum(int n){
if(n<0) return -1;
return 1;
}
long DayNumber(uint16_t y, uint8_t m, uint8_t d){
m = (m + 9) % 12;
y = y - m/10;
return 365*y + y/4 - y/100 + y/400 + (m*306 + 5)/10 + d - 1 ;
}
void Adjust(long offset){
long tmp, mod, nxt;
// offset is in minutes
tmp=dt[tl_minute]+offset; // minutes
nxt=tmp/60; // hours
mod=Absolute(tmp) % 60;
mod=mod*Signum(tmp)+60;
mod %= 60;
dt[tl_minute]=mod;
tmp=nxt+dt[tl_hour];
nxt=tmp/24; // days
mod=Absolute(tmp) % 24;
mod=mod*Signum(tmp)+24;
mod %= 24;
dt[tl_hour]=mod;
tmp=nxt+dt[tl_day];
mod=LengthOfMonth(dt);
dt[tl_day] = tmp;
if(tmp>mod){
while (tmp>mod) {
tmp -= mod;
dt[tl_month]++;
if (dt[tl_month] > 12) {
dt[tl_month] = 1;
dt[tl_year]++;
dt[tl_year] += 100;
dt[tl_year] %= 100;
}
mod = LengthOfMonth(dt);
}
dt[tl_day]=tmp;
} else if (tmp<1) {
while (tmp<1) {
dt[tl_month]--;
if (dt[tl_month] < 1) {
dt[tl_month] = 12;
dt[tl_year] --;
dt[tl_year] += 100;
dt[tl_year] %= 100;
}
mod=LengthOfMonth(dt);
dt[tl_day]=tmp+mod;
tmp += mod;
}
}
}
uint8_t ComputeSun(uint8_t rs) {
uint8_t month, day;
float y, decl, eqt, ha, lon, lat;
uint8_t a;
int minutes;
month=dt[tl_month]-1;
day=dt[tl_day]-1;
lon=-longitude/57.295779513082322;
lat=latitude/57.295779513082322;
//approximate hour;
a=6;
if(rs) a=18;
// approximate day of year
y= month * 30.4375 + day + a/24.0; // 0... 365
// compute fractional year
y *= 1.718771839885e-02; // 0... 1
// compute equation of time... .43068174
eqt=229.18 * (0.000075+0.001868*cos(y) -0.032077*sin(y) -0.014615*cos(y*2) -0.040849*sin(y* 2) );
// compute solar declination... -0.398272
decl=0.006918-0.399912*cos(y)+0.070257*sin(y)-0.006758*cos(y*2)+0.000907*sin(y*2)-0.002697*cos(y*3)+0.00148*sin(y*3);
//compute hour angle
ha=( cos(1.585340737228125) / (cos(lat)*cos(decl)) -tan(lat) * tan(decl) );
if(fabs(ha)>1.0){// we're in the (ant)arctic and there is no rise(or set) today!
return 0;
}
ha=acos(ha);
if(rs==0) ha=-ha;
// compute minutes from midnight
minutes=(int) (720+4*(lon-ha)*57.295779513082322-eqt);
// convert from UTC back to our timezone
minutes+= timezone;
// adjust the time array by minutes
dt[tl_hour]=0;
dt[tl_minute]=0;
dt[tl_second]=0;
Adjust(minutes);
return 1;
}