[PHP] Jak wyliczyć kiedy nastąpi wschód i zachód Słońca dla dowolnego dnia?
Chcesz obliczyć godziny wschodu i zachodu Słońca w dowolnym dniu, np. dzisiaj w Warszawie:
dzień: 13.05.2004
wschód Słońca: 04:44
zachód Słońca: 20:21
Gdy podajesz na swojej stronie dzisiejszą datę, możesz proste kalendarium wzbogacić o informację na temat wschodów i zachodów Słońca. Aby obliczyć godzinę wschodu oraz zachodu, musisz określić szerokość i długość geograficzną miejsca, dla którego będą liczone godziny, a także określić dzień, dla którego chcesz otrzymać wynik.
Algorytm obliczający czas wschodu i zachodu jest dosyć skomplikowany, oto on:
<?
$dzien="26";
$miesiac="04";
$rok="2004";
$szerokosc = 52.00; // szerokość geograficzna Warszawy
$dlugosc = 21.00; // długość geograficzna Warszawy
// wschód
$tw = floor(275*$miesiac/9)-(floor(($miesiac+9)/12)*
(1+floor(($rok-4*floor($rok/4)+2)/3)))+$dzien-30+(6-$dlugosc/15)/24;
$mw = (0.9856*$tw)-3.289;
$lw = $mw+1.916*sin($mw*M_PI/180)+0.020*sin(2*$mw*M_PI/180)+282.634;
if ($lw>360) $lw -= 360; if ($lw<0) $lw += 360;
$raw = atan(0.91764*tan($lw*M_PI/180))*180/M_PI;
if ($raw>360) $raw -= 360; if ($raw<0) $raw += 360;
$raw = ($raw+(floor($lw/90)*90-floor($raw/90)*90))/15;
$sinDecw = 0.39782*sin($lw*M_PI/180);
$cosDecw = cos(asin($sinDecw));
$cosHw = (cos(90.5)*M_PI/180-($sinDecw*sin($szerokosc*M_PI/180)))/
($cosDecw*cos($szerokosc*M_PI/180));
$UTw = (360-acos($cosHw)*180/M_PI)/15+$raw-0.06571*$tw-6.622-$dlugosc/15;
if ($UTw>24) $UTw -= 24; if ($UTw<0) $UTw += 24;
$cw = sprintf("%02d", (gmmktime()-mktime())/60/60+floor($UTw)).":";
$cw .= sprintf("%02d", floor((($UTw-floor($UTw))*60)));
// zachód
$tz = floor(275*$miesiac/9)-(floor(($miesiac+9)/12)*
(1+floor(($rok-4*floor($rok/4)+2)/3)))+$dzien-30+(18-$dlugosc/15)/24;
$mz = 0.9856*$tz-3.289;
$lz = $mz+1.916*sin($mz*M_PI/180)+0.020*sin(2*$mz*M_PI/180)+282.634;
if ($lz>360) $lz -= 360; if ($lz<0) $lz += 360;
$raz = atan(0.91764*tan($lz*M_PI/180))*180/M_PI;
if ($raz>360) $raz -= 360; if ($raz<0) $raz += 360;
$raz = ($raz+(floor($lz/90)*90-floor($raz/90)* 90))/15;
$sinDecz = 0.39782*sin($lz*M_PI/180);
$cosDecz = cos(asin($sinDecz));
$cosHz = (cos(90.5)*M_PI/180-($sinDecz*sin($szerokosc*M_PI/180)))/
($cosDecz*cos($szerokosc*M_PI/180));
$UTz = (acos($cosHz)*180/M_PI)/15+$raz-0.06571*$tz-6.622-$dlugosc/15;
if ($UTz>24) $UTz -= 24; if ($UTz<0) $UTz += 24;
$cz = sprintf("%02d", (gmmktime()-mktime())/60/60+floor($UTz)).":";
$cz .= sprintf("%02d", floor((($UTz-floor($UTz))*60)));
// wynik:
echo "<p><b>dzień:</b> $dzien.$miesiac.$rok";
echo "<br><b>wschód Słońca:</b> $cw";
echo "<br><b>zachód Słońca:</b> $cz";
?>
Algorytm pochodzi z książki Almanac for Computers, wydanej przez Nautical Almanac Office United States Naval Observatory. Przekształciłem go w wersję PHP dodając lub modyfikując nieco poszczególne kroki obliczeń.
Założyłem, iż odległość zenitalna dla słońca jest standardowa i wynosi 90.5 stopnia. Można jeszcze zastosować 96 stopni dla zenitu cywilnego, 102 stopnie dla zenitu żeglarskiego i 108 stopni dla astronomicznego.
Ponieważ należy określić położenie punktu, dla którego obliczany jest wschód i zachód, użyłem przybliżonych wartości dla Warszawy. Dzień można również ustalić według własnych potrzeb, jeżeli ma to być dzień aktualny możesz użyć formuły:
$dzien=date("d");
$miesiac=date("m");
$rok=date("Y");
Dalej następuje szereg obliczeń, mających na celu ustalenie dnia roku, wyliczenia pozycji Słońca na horyzoncie i przeliczenie jej na czas uniwersalny, a następnie lokalny przez dodanie do czasu uniwersalnego godziny lub dwóch w zależności od czasu letniego lub zimowego.
Wszystkie zmienne zakończone na "w" dotyczą wschodu, a zmienne zakończone na "z" dotyczą zachodu.
Nie brałem pod uwagę sytuacji, gdy Słońce nie zachodzi lub nie wschodzi (np. w określonych porach na biegunach). Jeżeli $cosHw jest większe niż 1, wtedy Słońce w danym dniu nie wschodzi, a jeżeli $cosHz jest mniejsze niż -1, wtedy nie zachodzi.