Mondphasen

98%
Vollmond abnehmender Mond Neumond zunehmender Mond Vollmond
Derzeit ist zunehmender Mond.
Mondphase | Datum | Uhrzeit | ||
---|---|---|---|---|
UT | MEZ | MESZ | ||
Neumond | 21.01.2023 | 20:55:56 | 21:55:56 | 22:55:56 |
erste Viertel | 28.01.2023 | 15:22:30 | 16:22:30 | 17:22:30 |
Vollmond | 05.02.2023 | 18:30:56 | 19:30:56 | 20:30:56 |
letzte Viertel | 13.02.2023 | 16:02:42 | 17:02:42 | 18:02:42 |
Genauigkeit der Mondphasen-Berechnung
Jeder der auf seiner Website die Mondphasen präsentieren will muss sich vorher Gedanken über die Genauigkeit der Darstellung machen.
Es gibt meiner Meinung nach drei gangbare Wege:
- Die sekundengenaue Berechnung.
- Die Berechnung, auf +/- 10 Minuten
- Die Berechnung auf +/- 1 Tag
- Die sekundengenaue Berechnung ist sehr aufwendig und auch nicht leicht und eigentlich nur sinnvol, wenn die Werte in einem astronomischen Zusammenhang verwendet werden sollen.
- Die Berechnung mit einer Genauigkeit von wenigen Minuten ist sehr viel weniger aufwendig. Man kann die benötigten Korrekturwerte aus dem Internet rechergieren ohne die astronomischen und mathematischen Hintergründe zu verstehen. Obwohl hier "minutengenau" gerechnet wird, kann das Datum den falschen Tag zeigen, wenn das Ereignis in die Nähe von Mitternacht (0:00 Uhr) fällt.
- Eine tagesgenaue Darstellung der Mondphasen ist sehr einfach, da man keinerlei Korrekturwerte benötigt. Lediglich die Umlaufzeit des Mondes um die Erde muss man kennen. (Achtung: Es gibt zwei Werte die gebräuchlich sind. Für die Mondphasenberechnung braucht man den Mittelwert des "synodischen Monat").
Der Mittelwert des synodischen Monats beträgt 29.530588861 Tage. Dies ist aber wirklich nur ein Mittelwert. Auf Grund der komplizierten Mondbahn weicht der tatsächliche synodische Monat bis zu +/- 7 Stunden von diesem Mittelwert ab. Dadurch ergibt sich die "tagesgenaue" Berechnung, wenn man nur mit dem Mittelwert rechnet.
Mein Script
Mein Script ist eine Mischung aus der "tagesgenauen" und der "minutengenauen" Berechnung. Für die Balkenanzeige mit der %-Angabe der Mondphase verwende ich die tagesgenaue Berechnung. Für die Anzeige der nächsten Mondphasen-Ereignisse (Neumond, Vollmond, erstes Viertel und letztes Viertel) habe ich entsprechende Korrekturwerte im Internet gefunden (ich selbst kann diese nicht berechnen) und komme damit auf eine Genauigkeit von wenigen Minuten, die meiner Meinung nach absolut ausreichend ist. Und obwohl ich weiß, das es Unsinn ist, mache ich die Zeitangaben sekundengenau.
In meinem Script ist noch ein weiterer Fehler vorhanden:
Ich zeige die Uhrzeit der nächsten Ereignisse sowohl in der berechneten UT (universal time) als auch in MEZ (mittel-europäische Zeit; UT + 1 Std.) und in MESZ (mittel-europäschie Sommerzeit; MEZ + 1 Std.) an.
Da ich das Datum aber nur einmal anzeige, stimmt es für MESZ nicht mehr, wenn UT 22:00:00 Uhr oder später ist. Wenn UT 23:00:00 Uhr oder später ist, stimmt das Datum sowohl für MESZ als auch für
MEZ nicht mehr. In beiden Fällen ist der nächste Kalendertag das richtige Datum für MEZ und MESZ. Diesen Fehler kann man leicht umgehen, wenn die Ereignisse nur in UT angezeigt werden
und die Umrechnung dem Betrachter überlassen wird. Oder man macht die Darstellung etwas aufwendiger und zeigt bei MEZ und MESZ jeweils das Datum mit an.
Fachleuten wird noch etwas auffallen: Meine Darstellung der Mondphase entspricht nicht der heute gebräuchlichen Form (Neumond bis nächster Neumond). Bei mir geht die Mondphase von Vollmond bis zum nächsten Vollmond. Das ist die ursprüngliche Form der Mondphase (früher war der Vollmond besser zu beobachten als der Neumond) und mir persönlich gefällt es einfach besser.
Der Programmcode
Hier zeige ich, wie ich die wichtigen Werte ermittel. Als erstes fange ich mit der Berechnung der Mondphase in % sowie zwei "Hilfsvariablen" an:
<?php
$ursprung = mktime(18,31,18,12,22,1999);
$akt_date = time();
define('ZYCLUS', floor(29.530588861 * 86400));
$mondphase = round(((($akt_date - $ursprung) / ZYCLUS) - floor(($akt_date - $ursprung) / ZYCLUS)) * 100, 0);
$mondphasen_img = round(($mondphase /50),1) *50;
if ($mondphasen_img == 100) $mondphasen_img == 0;
if ($mondphase <= 1 || $mondphase >= 99 ) $phase_text = 'Vollmond';
elseif ($mondphase > 1 && $mondphase < 49) $phase_text = 'abnehmender Mond';
elseif ($mondphase >= 49 && $mondphase <= 51) $phase_text = 'Neumond';
else $phase_text = 'zunehmender Mond';
?>
Erklärung
Das Prinzip der Mondphasenberechnung in % ist sehr einfach:
Man nehme ein bekanntes Ereignisdatum ($ursprung; in meinem Fall den 22.12.1999 18:31:18 Uhr) und ermittelt die seit diesem Zeitpunkt vergangenen synodischen
Monate (Mondumläufe bzw. Mondphasen).
<?php
($akt_date - $ursprung) / ZYCLUS
?>
Von dem Ergebnis interessiert uns nur der Nachkommateil.
<?php
(($akt_date - $ursprung) / ZYCLUS) - floor(($akt_date - $ursprung) / ZYCLUS)
?>
Wenn wir diesen Teil mit 100 multiplizieren, haben wir die aktuelle Mondphase in %, die dann noch auf volle % gerundet wird.
<?php
round(((($akt_date - $ursprung) / ZYCLUS) - floor(($akt_date - $ursprung) / ZYCLUS)) * 100, 0)
?>
Hier kommt jetzt der restliche Code, um ein minutengenaues Datum mit Uhrzeit für die Phasen "Neumond", "erstes Viertel", "Vollmond" und "letztes Viertel" zu bekommen. Ich werde diese Berechnung nicht weiter kommentieren. Der Code ist abgeleitet von einem veröffentlichten Programm für einen Taschenrechner und von mir nur in PHP umgeschrieben.
<?php
// ============================================================
// Angaben:
// Phasen: phase = 0 für Neumond
// phase = 0.25 für erstes Viertel
// phase = 0.5 für Vollmond
// phase = 0.75 für letztes Viertel
// Für Werte anders als 0, 0.25, 0.5 oder 0.75 ist nachstehendes Script ungültig.
// Angabe des Zeitpunktes als Fließkomma-Jahreszahl
// Bsp.: 1.8.2006 = ca. 2006.581
//
// Ergebniss: $JDE
// ============================================================
//
//aktuelles Datum in Jahre umrechnen
$year = ((((((date("s") / 60)+ date("i")) / 60)+date("G")) / 24) + date("z") - 1) / (365 + (date("L"))) + date("Y");
//
$rads = 3.14159265359/180;
for ($phase = 0; $phase < 1; $phase += 0.25) {
//Anzahl der Mondphasen seit 2000
$k = floor(($year-2000)*12.36853087)+$phase;
// Mittlerer JDE Wert des Ereignisses
$JDE = 2451550.09766+29.530588861*$k;
// Relevante Winkelwerte in [Radiant]
$M = (2.5534+29.10535670*$k)*$rads;
$Ms = (201.5643+385.81693528*$k)*$rads;
$F = (160.7108+390.67050284*$k)*$rads;
//
if ($phase == 0) {
// Korrekturterme JDE für Neumond
$JDE += -0.40720*Sin($Ms);
$JDE += 0.17241*Sin($M);
$JDE += 0.01608*Sin(2*$Ms);
$JDE += 0.01039*Sin(2*$F);
$JDE += 0.00739*Sin($Ms-$M);
$JDE += -0.00514*Sin($Ms+$M);
$JDE += 0.00208*Sin(2*$M);
$JDE += -0.00111*Sin($Ms-2*$F);
}
elseif ($phase == 0.5) {
// Korrekturterme JDE für Vollmond
$JDE += -0.40614*Sin($Ms);
$JDE += 0.17302*Sin($M);
$JDE += 0.01614*Sin(2*$Ms);
$JDE += 0.01043*Sin(2*$F);
$JDE += 0.00734*Sin($Ms-$M);
$JDE += -0.00515*Sin($Ms+$M);
$JDE += 0.00209*Sin(2*$M);
$JDE += -0.00111*Sin($Ms-2*$F);
}
if ($phase == 0.25 || $phase == 0.75) {
// Korrekturterme für JDE für das 1. bzw. letzte Viertel
$JDE += -0.62801*Sin($Ms);
$JDE += 0.17172*Sin($M);
$JDE += -0.01183*Sin($Ms+$M);
$JDE += 0.00862*Sin(2*$Ms);
$JDE += 0.00804*Sin(2*$F);
$JDE += 0.00454*Sin($Ms-$M);
$JDE += 0.00204*Sin(2*$M);
$JDE += -0.00180*Sin($Ms-2*$F);
//
// Weiterer Korrekturterm für Viertelphasen
if ($phase == 0.25) {
$JDE += 0.00306;
} else {
$JDE += -0.00306;
}
}
//
//Konvertierung von Julianischem Datum auf Gregorianisches Datum
$z = floor($JDE + 0.5);
$f = ($JDE + 0.5) - floor($JDE + 0.5);
if ($z < 2299161) {
$a = $z;
}
else {
$g = floor(($z - 1867216.25) / 36524.25);
$a = $z + 1 + $g - floor($g / 4);
}
$b = $a + 1524;
$c = floor(($b - 122.1) / 365.25);
$d = floor(365.25 * $c);
$e = floor(($b - $d) / 30.6001);
$tag_temp = $b - $d - floor(30.6001 * $e) + $f; //Tag incl. Tagesbruchteilen
$stunde_temp = ($tag_temp - floor($tag_temp)) * 24;
$minute_temp = ($stunde_temp - floor($stunde_temp)) * 60;
$stunde = floor($stunde_temp);
$minute = floor($minute_temp);
$sekunde = round(($minute_temp - floor($minute_temp)) * 60);
$tag = floor($tag_temp);
if ($e < 14) {
$monat = $e -1;
}
else {
$monat = $e - 13;
}
if ($monat > 2) {
$jahr = $c - 4716;
}
else {
$jahr = $c - 4715;
}
$datum = mktime($stunde,$minute,$sekunde,$monat,$tag,$jahr);
$datum_mez = $datum + 3600;
$datum_mesz = $datum_mez + 3600;
switch ($phase) {
case 0:
$ausgabe = 'Neumond';
break;
case 0.25:
$ausgabe = 'erste Viertel';
break;
case 0.5:
$ausgabe = 'Vollmond';
break;
case 0.75:
$ausgabe = 'letzte Viertel';
break;
}
}?>
Die Datumswerte stehen jetzt in den Variablen: $datum, $datum_mez und $datum_mesz. Diese Werte können nach belieben ausgegeben werden.
Ich hoffe, das dieses kleine Script vielleicht dem Einen oder Anderem hilft. Wenn Fehler entdeckt werden oder Verbesserungen gemacht werden sollten, teilt mir das bitte im Kontaktformular mit.