long daylight_seconds(const time_t * timer) { double l, d; long n; /* convert latitude to radians */ l = __latitude / 206264.806; d = -solar_declination(timer); /* partial 'Sunrise Equation' */ d = tan(l) * tan(d); /* magnitude of d may exceed 1.0 at near solstices */ if (d > 1.0) d = 1.0; if (d < -1.0) d = -1.0; /* derive hour angle */ d = acos(d); /* but for atmospheric refraction, this would be d /= M_PI */ d /= 3.112505; n = ONE_DAY * d; return n; }
/* Solar angular elevation at the given location and time. t: Julian centuries since J2000.0 lat: Latitude of location lon: Longitude of location Return: Solar angular elevation in radians */ static double solar_elevation_from_time(double t, double lat, double lon) { /* Minutes from midnight */ double jd = jd_from_jcent(t); double offset = (jd - round(jd) - 0.5)*1440.0; double eq_time = equation_of_time(t); double ha = RAD((720 - offset - eq_time)/4 - lon); double decl = solar_declination(t); return elevation_from_hour_angle(lat, decl, ha); }
/* Time of given apparent solar angular elevation of location on earth. t: Julian centuries since J2000.0 t_noon: Apparent solar noon in Julian centuries since J2000.0 lat: Latitude of location in degrees lon: Longtitude of location in degrees elev: Solar angular elevation in radians Return: Time difference from mean solar midnight in minutes */ static double time_of_solar_elevation(double t, double t_noon, double lat, double lon, double elev) { /* First pass uses approximate sunrise to calculate equation of time. */ double eq_time = equation_of_time(t_noon); double sol_decl = solar_declination(t_noon); double ha = hour_angle_from_elevation(lat, sol_decl, elev); double sol_offset = 720 - 4*(lon + DEG(ha)) - eq_time; /* Recalculate using new sunrise. */ double t_rise = jcent_from_jd(jd_from_jcent(t) + sol_offset/1440.0); eq_time = equation_of_time(t_rise); sol_decl = solar_declination(t_rise); ha = hour_angle_from_elevation(lat, sol_decl, elev); sol_offset = 720 - 4*(lon + DEG(ha)) - eq_time; /* No need to do more iterations */ return sol_offset; }