function _weather_sunrise_sunset in Weather 5
Internal helper function to calculate the sunrise and sunset times for a given location
1 call to _weather_sunrise_sunset()
File
- ./
weather.module, line 224 - Display <acronym title="METeorological Aerodrome Report">METAR</acronym> weather data from anywhere in the world
Code
function _weather_sunrise_sunset($metar) {
// Include the ICAO codes
require_once drupal_get_path('module', 'weather') . '/icao_codes.inc';
$info = _weather_get_lat_long($metar['icao']);
// reported_on is already GMT, so don't use gmdate()
$day_of_year = date('z', $metar['reported_on']);
$year = date('Y', $metar['reported_on']);
$month = date('m', $metar['reported_on']);
$day = date('d', $metar['reported_on']);
// setup pi constants: 0.5*pi, 1.0*pi, 1.5*pi, 2.0*pi
$pi_05 = 1.570796;
$pi_10 = 3.141593;
$pi_15 = 4.712389;
$pi_20 = 6.283185;
// convert latitude and longitude degree into radian
// x rad = y° * pi / 180 = 0.017453 * y°
$latitude = 0.017453 * $info['lat'];
$longitude = 0.017453 * $info['long'];
// we want always GMT time, so set to 0. Otherwise,
// the timezone can be calculated as follows:
// $timezone = 0.261799 * offset;
$timezone = 0;
// the sunrise/sunset altitude in radian (-0.833°)
$altitude = -0.014539;
$sunrise = 0;
$sunset = 0;
foreach (array(
'sunrise' => $pi_05,
'sunset' => $pi_15,
) as $type => $factor) {
$a = $day_of_year + ($factor - $longitude) / $pi_20;
// solar mean anomaly
$sma = $a * 0.017202 - 0.0574039;
// solar true longitude
$stl = $sma + 0.0334405 * sin($sma);
$stl += 4.93289 + 0.000349066 * sin(2 * $sma);
// normalize the longitude to be between >= 0 and < 2.0*pi
while ($stl < 0) {
$stl += $pi_20;
}
while ($stl >= $pi_20) {
$stl -= $pi_20;
}
if ($stl / $pi_05 - intval($stl / $pi_05) == 0) {
$stl += 4.84814E-6;
}
// solar right ascension
$sra = sin($stl) / cos($stl);
$sra = atan2(0.9174600000000001 * $sra, 1);
// adjust quadrant
if ($stl > $pi_15) {
$sra += $pi_20;
}
else {
if ($stl > $pi_05) {
$sra += $pi_10;
}
}
// solar declination
$sd = 0.39782 * sin($stl);
$sd = $sd / sqrt(1 - $sd * $sd);
$sd = atan2($sd, 1);
$diurnal_arc = ($altitude - sin($sd) * sin($latitude)) / (cos($sd) * cos($latitude));
// is there a sunrise or sunset at all?
if ($diurnal_arc >= 1) {
// no sunrise
$no_sunrise = TRUE;
break;
}
if ($diurnal_arc <= -1) {
// no sunset
$no_sunset = TRUE;
break;
}
$diurnal_arc = $diurnal_arc / sqrt(1 - $diurnal_arc * $diurnal_arc);
$diurnal_arc = $pi_05 - atan2($diurnal_arc, 1);
if ($type == 'sunrise') {
$diurnal_arc = $pi_20 - $diurnal_arc;
}
// calculate the time
$localtime = $diurnal_arc + $sra - 0.0172028 * $a - 1.73364;
// wall clock time
$wallclock = $localtime - $longitude + $timezone;
// normalize wallclock to be between >= 0 and < 2.0*pi
while ($wallclock < 0) {
$wallclock += $pi_20;
}
while ($wallclock >= $pi_20) {
$wallclock -= $pi_20;
}
$wallclock = $wallclock * 3.81972;
$hour = intval($wallclock);
$minute = round(($wallclock - $hour) * 60, 0);
if ($type == 'sunrise') {
$sunrise = gmmktime($hour, $minute, 0, $month, $day, $year);
}
else {
$sunset = gmmktime($hour, $minute, 0, $month, $day, $year);
}
}
// handle special cases like no sunrise / sunset at all
if ($no_sunset) {
$condition = 'day';
}
else {
if ($no_sunrise) {
$condition = 'night';
}
else {
// correctly handle northern and southern hemisphere
if ($sunrise <= $sunset) {
// this should be on the northern hemisphere
if ($metar['reported_on'] >= $sunrise and $metar['reported_on'] < $sunset) {
$condition = 'day';
}
else {
$condition = 'night';
}
}
else {
// this should be on the southern hemisphere
if ($metar['reported_on'] >= $sunrise or $metar['reported_on'] <= $sunset) {
$condition = 'day';
}
else {
$condition = 'night';
}
}
}
}
return $condition;
}