ThemeScheduler.cpp
1 #include "ThemeScheduler.h" 2 #include <utility> 3 4 SunTimes CalculateSunriseSunset(double latitude, double longitude, int year, int month, int day) 5 { 6 double zenith = 90.833; 7 int N1 = static_cast<int>(floor(275.0 * month / 9.0)); 8 int N2 = static_cast<int>(floor((static_cast<double>(month) + 9) / 12.0)); 9 int N3 = static_cast<int>(floor((1.0 + floor((year - 4.0 * floor(year / 4.0) + 2.0) / 3.0)))); 10 int N = N1 - (N2 * N3) + day - 30; 11 12 auto calcTime = [&](bool sunrise) -> double { 13 double lngHour = longitude / 15.0; 14 double t = sunrise ? N + ((6 - lngHour) / 24) : N + ((18 - lngHour) / 24); 15 16 double M = (0.9856 * t) - 3.289; 17 double L = M + (1.916 * sin(deg2rad(M))) + (0.020 * sin(2 * deg2rad(M))) + 282.634; 18 if (L < 0) 19 L += 360; 20 if (L > 360) 21 L -= 360; 22 23 double RA = rad2deg(atan(0.91764 * tan(deg2rad(L)))); 24 if (RA < 0) 25 RA += 360; 26 if (RA > 360) 27 RA -= 360; 28 29 double Lquadrant = floor(L / 90) * 90; 30 double RAquadrant = floor(RA / 90) * 90; 31 RA = RA + (Lquadrant - RAquadrant); 32 RA /= 15; 33 34 double sinDec = 0.39782 * sin(deg2rad(L)); 35 double cosDec = cos(asin(sinDec)); 36 37 double cosH = (cos(deg2rad(zenith)) - (sinDec * sin(deg2rad(latitude)))) / (cosDec * cos(deg2rad(latitude))); 38 if (cosH > 1 || cosH < -1) 39 return -1; 40 41 double H = sunrise ? 360 - rad2deg(acos(cosH)) : rad2deg(acos(cosH)); 42 H /= 15; 43 44 double T = H + RA - (0.06571 * t) - 6.622; 45 double UT = T - lngHour; 46 while (UT < 0) 47 UT += 24; 48 while (UT >= 24) 49 UT -= 24; 50 51 return UT; 52 }; 53 54 double riseUT = calcTime(true); 55 double setUT = calcTime(false); 56 57 auto toLocal = [](double UT) { 58 TIME_ZONE_INFORMATION tz; 59 DWORD state = GetTimeZoneInformation(&tz); 60 double totalBias = tz.Bias; 61 62 if (state == TIME_ZONE_ID_DAYLIGHT) 63 totalBias += tz.DaylightBias; 64 else if (state == TIME_ZONE_ID_STANDARD) 65 totalBias += tz.StandardBias; 66 67 double biasHours = -(totalBias / 60.0); 68 double localTime = UT + biasHours; 69 70 while (localTime < 0) 71 localTime += 24; 72 while (localTime >= 24) 73 localTime -= 24; 74 75 int hour = static_cast<int>(localTime); 76 int minute = static_cast<int>((localTime - hour) * 60); 77 return std::pair<int, int>{ hour, minute }; 78 }; 79 80 auto [riseHour, riseMinute] = toLocal(riseUT); 81 auto [setHour, setMinute] = toLocal(setUT); 82 83 SunTimes result; 84 result.sunriseHour = riseHour; 85 result.sunriseMinute = riseMinute; 86 result.sunsetHour = setHour; 87 result.sunsetMinute = setMinute; 88 return result; 89 }