5

Mond, moon, Mondphase

Hallo Freunde nebensächlicher Scripte. Ich teile hier mal ein "Widget" von mir. Es liefert Euch drei aktuelle Informationen über den Mond.
1. die Richtung (zu- oder abnehmend) der Phase, 2. die beleuchtete Fläche (eben jene Phase in %) und 3. die Orbitposition seines Umlaufs. Im Test (timeanddate.com) war es für private Spielereien absolut genau genug. Die Phase weicht um bis zu 0,2% ab. Die Berechnung basiert auf dem Inhalt in einem Astronomiebuch. Die Kalkulationen habe ich in NX übersetzt. Die html-Spielerei kann natürlich nach Bedarf durch join() ersetzt werden. Wer sich ein "Datum+Uhrzeit"-Feld anlegt, und dieses statt now() im Script einbindet, kann auch schauen, ob zu Weihnachten 2026 Vollmond ist (spoiler: ja). Also, wer wissen will, warum man mal wieder nicht schlafen konnte, oder wann es Zeit ist für einen Mondscheinspaziergang, braucht nur Ninox, kein API, kein Internet, kein outdoor.

;-) Gruß Mirko

let myDate := now();
let pi := 3.1415927;
let e := 0.016705;
let Eg := 279.557208;
let Wg := 283.112438;
let l0 := 91.929336;
let P0 := 130.143076;
let epoch := datetime(2010, 1, 0);
let daysSinceEpoch := (number(myDate) - number(epoch)) / 1000 / 60 / 60 / 24;
let Ns := 360 / 365.242191 * daysSinceEpoch;
switch Ns != 0 do
case Ns < 0:
    while Ns < 0 do 
        Ns := Ns + 360
    end

case Ns > 360:
    while Ns > 360 do 
        Ns := Ns - 360
    end

default:
    0
end;
let Mo := (
        let result := Ns + Eg - Wg;
        if result < 0 then result + 360 else result end
    );
let MoRad := radians(Mo);
let EcS := 360 / pi * e * sin(MoRad);
let lambdaSun := (
        let result := Ns + EcS + Eg;
        if result > 360 then result - 360 else result end
    );
let l := 13.1763966 * daysSinceEpoch + l0;
switch l != 0 do
case l < 0:
    while l < 0 do 
        l := l + 360
    end

case l > 360:
    while l > 360 do 
        l := l - 360
    end

default:
    0
end;
let MmO := l - 0.111404 * daysSinceEpoch - P0;
let Mm := if MmO > 360 then MmO - 360 else MmO end;
let MmRad := radians(Mm);
let C := l - lambdaSun;
let CRad := radians(C);
let Ev := 1.2739 * sin(2 * CRad - MmRad);
let Ae := 0.1858 * sin(MoRad);
let A3 := 0.37 * sin(MoRad);
let MmStrich := Mm + Ev - Ae - A3;
let MmStrichRad := MmStrich * pi / 180;
let Ec := 6.2886 * sin(MmStrichRad);
let A4 := 0.214 * sin(2 * MmStrichRad);
let lStrich := l + Ev + Ec - Ae + A4;
let lStrichRad := radians(lStrich);
let lambdaSunRad := radians(lambdaSun);
let V := 0.6583 * sin(2 * (lStrichRad - lambdaSunRad));
let lStrichStrich := lStrich + V;
let DD := lStrichStrich - lambdaSun;
let DDRad := radians(DD);
let lunarPhasePercent := round(0.5 * (1 - cos(DDRad)) * 100, 1);
switch DD != 0 do
case DD < 0:
    while DD < 0 do 
        DD := DD + 360
    end

case DD > 360:
    while DD > 360 do 
        DD := DD - 360
    end

default:
    0
end;
let lunarPhaseGrad := round(DD, 1);
let display := switch lunarPhaseGrad != -1 do
    case lunarPhaseGrad > 2 and lunarPhaseGrad <= 80:
        "zunehmender Sichelmond 🌒"
    case lunarPhaseGrad > 80 and lunarPhaseGrad <= 100:
        "zunehmender Halbmond 🌓"
    case lunarPhaseGrad > 100 and lunarPhaseGrad < 178:
        "zunehmender Dreiviertelmond 🌔"
    case lunarPhaseGrad >= 178 and lunarPhaseGrad <= 182:
        "Vollmond 🌕"
    case lunarPhaseGrad > 182 and lunarPhaseGrad <= 260:
        "abnehmender Dreiviertelmond 🌖"
    case lunarPhaseGrad > 260 and lunarPhaseGrad <= 280:
        "abnehmender Halbmond 🌗"
    case lunarPhaseGrad > 280 and lunarPhaseGrad < 358:
        "abnehmender Sichelmond 🌘"
    case lunarPhaseGrad >= 358:
        "Neumond 🌑"
    case lunarPhaseGrad <= 2:
        "Neumond 🌑"
    end;
let first := display;
let second := lunarPhasePercent + " %  Mondphase";
let third := text(lunarPhaseGrad) + "° Orbit";
html("<style>" + "p" + "{border-radius: .5em;box-shadow: .3em .3em .6em #2D2F62;margin: 1em;padding: .3em 1em;box-decoration-break: slice;
text-align:center;background-color: #C7E1FB;font: bold 1em Georgia, serif;}" + "</style>" + "<p style='color:#002F9A'>" + "<br>" + third + "</br>" + "<br>" + first + "</br>" + "<br>" + second + "</br>" + "<br>" + "" + "</br>" + "</p>")

5 Antworten

null
    • Michael.3
    • vor 2 Jahren
    • Gemeldet - anzeigen

    cool!

    • mirko3
    • vor 2 Jahren
    • Gemeldet - anzeigen

    sorry, Zeile 8 heißt:

    let epoch := number(datetime(2010, 1, 0, 1));

    • Ninox-Professional
    • planoxpro
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Es sind doch gerade Nebensächlichkeiten, die den tristen Alltag auflockern. ;)

    • mirko3
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hier mal ein "Update" für Interessenten astronomischer Berechnungen. Code muss in ein Funktionsfeld. Kaum Rechenkapazität und natürlich könnt ihr statt Krakvitz jeden anderen Ort in der mitteleuropäischen Zeitzone (MEZ) eingeben. Die ersten vier Variablen können auch durch ein Standortfeld und ein Timestamp-Feld beschickt werden. Mirko

    "Koordinaten im Format Dezimalgrad eingeben Beliebigen Zeitstempel - hier now() und Name des Ortes eigeben";
    let lat := 54.327033;
    let long := 13.432921;
    let timeStamp := Timestamp;
    let place := "Krakvitz";
    "---------------------------";
    let breiteRad := radians(lat);
    let longDir := if long > 0 then "° O" else "° W" end;
    let latDir := if lat > 0 then "° N" else "° S" end;
    let utcDiff := format(timeStamp, "ZZ");
    "Funktion zur Korrektur der Zeit auf UTC";
    function UTCCorrection(currentDate : datetime) do
        let hour := number(extractx(format(currentDate, "Z"), "\d+(?=:)"));
        let min := number(extractx(format(currentDate, "Z"), "\d+(?=$)"));
        let sign := extractx(format(currentDate, "Z"), "^.");
        let utcCorrectionTime := time(hour, min);
        if sign = "+" then
            currentDate - utcCorrectionTime
        else
            currentDate + utcCorrectionTime
        end
    end;
    "Funktion zur Überprüfung, ob aktuelles Datum Sommerzeit ist";
    function isSoWi() do
        let counter := days(date(year(timeStamp), 1, 1), date(year(timeStamp), 12, 31));
        let sowi := unique(for i in range(0, counter + 1) do
                    if format(date(year(timeStamp), 1, 1) + i, "Z") != format(date(year(timeStamp), 1, 1) + i + 1, "Z") then
                        date(year(timeStamp), 1, 1) + i
                    end
                end);
        if cnt(sowi) = 2 and date(timeStamp) > item(sowi, 0) and date(timeStamp) < item(sowi, 1) then
            true
        else
            false
        end
    end;
    function Sunrise(lat : number,long : number,curDateTime : datetime) do
        let zeitzone := number(extractx(format(curDateTime, "Z"), "\d+(?=:)"));
        let breiteRad := 3.14159 * lat / 180;
        let dayCount := days(date(year(curDateTime), 1, 0), date(year(curDateTime), month(curDateTime), day(curDateTime)));
        let deklination := 0.4095 * sin(0.016906 * (dayCount - 80.086));
        let zeitdifferenz := 12 * acos((sin(-0.0145) - sin(breiteRad) * sin(deklination)) / (cos(breiteRad) * cos(deklination))) / 3.14159;
        let zeitgleichung := -0.171 * sin(0.0337 * dayCount + 0.465) - 0.1299 * sin(0.01787 * dayCount - 0.168);
        let sunRise := 12 - zeitdifferenz - zeitgleichung;
        let sunRiseCorr := sunRise - long / 15 + zeitzone;
        time(sunRiseCorr, 0)
    end;
    function Sunset(lat : number,long : number,curDateTime : datetime) do
        let zeitzone := number(extractx(format(curDateTime, "Z"), "\d+(?=:)"));
        let breiteRad := 3.14159 * lat / 180;
        let dayCount := days(date(year(curDateTime), 1, 0), date(year(curDateTime), month(curDateTime), day(curDateTime)));
        let deklination := 0.4095 * sin(0.016906 * (dayCount - 80.086));
        let zeitdifferenz := 12 * acos((sin(-0.0145) - sin(breiteRad) * sin(deklination)) / (cos(breiteRad) * cos(deklination))) / 3.14159;
        let zeitgleichung := -0.171 * sin(0.0337 * dayCount + 0.465) - 0.1299 * sin(0.01787 * dayCount - 0.168);
        let sunSet := 12 + zeitdifferenz - zeitgleichung;
        let sunSetCorr := sunSet - long / 15 + zeitzone;
        time(sunSetCorr, 0)
    end;
    "Im Anschluss finden sich die eigentlichen astronomischen Berechnungen mit diversen Korrekturfaktoren, die von viel schlaueren Leuten stammen";
    let pi := 3.1415927;
    let e := 0.016705;
    let Eg := 279.557208;
    let Wg := 283.112438;
    let l0 := 91.929336;
    let P0 := 130.143076;
    let epochDateTime := datetime(2010, 1, 0);
    let nowDateTime := UTCCorrection(timeStamp);
    let daysSinceEpoch := (number(nowDateTime) - number(epochDateTime) + if isSoWi() then 3600000 end) / 1000 / 60 / 60 / 24;
    let Ns := 360 / 365.242191 * daysSinceEpoch;
    switch Ns != 0 do
    case Ns < 0:
        while Ns < 0 do
            Ns := Ns + 360
        end
    
    case Ns > 360:
        while Ns > 360 do
            Ns := Ns - 360
        end
    
    default:
        0
    end;
    let Mo := (
            let result := Ns + Eg - Wg;
            if result < 0 then result + 360 else result end
        );
    let MoRad := radians(Mo);
    let EcS := 360 / pi * e * sin(MoRad);
    let lambdaSun := (
            let result := Ns + EcS + Eg;
            if result > 360 then result - 360 else result end
        );
    let l := 13.1763966 * daysSinceEpoch + l0;
    switch l != 0 do
    case l < 0:
        while l < 0 do
            l := l + 360
        end
    
    case l > 360:
        while l > 360 do
            l := l - 360
        end
    
    default:
        0
    end;
    "Weitere astronomische Konstanten und Korrekturfaktoren. Die Berechnungen drehen sich im Wesentlichen um die Bahnen dreier Himmelskörper: Erde, Mond, Sonne.";
    let MmO := l - 0.111404 * daysSinceEpoch - P0;
    let Mm := if MmO > 360 then MmO - 360 else MmO end;
    let MmRad := radians(Mm);
    let C := l - lambdaSun;
    let CRad := radians(C);
    let Ev := 1.2739 * sin(2 * CRad - MmRad);
    let Ae := 0.1858 * sin(MoRad);
    let A3 := 0.37 * sin(MoRad);
    let MmStrich := Mm + Ev - Ae - A3;
    let MmStrichRad := MmStrich * pi / 180;
    let Ec := 6.2886 * sin(MmStrichRad);
    let A4 := 0.214 * sin(2 * MmStrichRad);
    let lStrich := l + Ev + Ec - Ae + A4;
    let lStrichRad := radians(lStrich);
    let lambdaSunRad := radians(lambdaSun);
    let V := 0.6583 * sin(2 * (lStrichRad - lambdaSunRad));
    let lStrichStrich := lStrich + V;
    let DD := lStrichStrich - lambdaSun;
    let DDRad := radians(DD);
    let lunarPhasePercent := round(0.5 * (1 - cos(DDRad)) * 100, 1);
    switch DD != 0 do
    case DD < 0:
        while DD < 0 do
            DD := DD + 360
        end
    
    case DD > 360:
        while DD > 360 do
            DD := DD - 360
        end
    
    default:
        0
    end;
    "Der vollständige Orbit des Mondes von 360° beginnt mit Neumond und endet mit Neumond, also sind alle Werte bis 180° zunehmend, dann abnehmend.";
    let lunarPhaseGrad := round(DD, 1);
    let display := switch lunarPhaseGrad != -1 do
        case lunarPhaseGrad > 2 and lunarPhaseGrad <= 80:
            "&uarr; " + "waxing crescent"
        case lunarPhaseGrad > 80 and lunarPhaseGrad <= 100:
            "&uarr; " + "first quarter"
        case lunarPhaseGrad > 100 and lunarPhaseGrad < 178:
            "&uarr; " + "waxing gibbous"
        case lunarPhaseGrad >= 178 and lunarPhaseGrad <= 182:
            "&#127773; full moon"
        case lunarPhaseGrad > 182 and lunarPhaseGrad <= 260:
            "&darr; " + "waning gibbous"
        case lunarPhaseGrad > 260 and lunarPhaseGrad <= 280:
            "&darr; " + "last quarter"
        case lunarPhaseGrad > 280 and lunarPhaseGrad < 358:
            "&darr; " + "waning crescent"
        case lunarPhaseGrad >= 358:
            "new moon"
        case lunarPhaseGrad <= 2:
            "new moon"
        end;
    let outputLunarPhasePercent := lunarPhasePercent + "%";
    let outputLunarPhaseGrade := text(lunarPhaseGrad) + "°";
    "Berechnung Sonnenaufgang und Sonnneuntergang, Tageslänge und Differenz der Tageslänge zu gestern";
    let sunrise := Sunrise(lat, long, timeStamp);
    let sunset := Sunset(lat, long, timeStamp);
    let dayLengthToday := sunset - sunrise;
    let outputDayLengthToday := replacex(text(sunset - sunrise), "\.\d{3}$", "");
    let sunriseYesterday := Sunrise(lat, long, datetime(number(timeStamp) - 86400000));
    let sunsetYesterday := Sunset(lat, long, datetime(number(timeStamp) - 86400000));
    let dayLengthYesterday := sunsetYesterday - sunriseYesterday;
    let outputDayLengthYesterday := replacex(text(sunsetYesterday - sunriseYesterday), "\.\d{3}$", "");
    let dayDiff := dayLengthToday - dayLengthYesterday;
    let dayDiffCorr := time(abs(number(dayLengthToday - dayLengthYesterday)));
    let outputDayDiff := if dayDiff < 0 then
            "- " + format(datetime(date(today()), dayDiffCorr), "mm:ss")
        else
            "+ " + format(datetime(date(today()), dayDiffCorr), "mm:ss")
        end;
    "Ausgabe der Sommer- oder Winterzeit als Text";
    let sowi := format(timeStamp, "Z");
    let resultSoWi := if sowi = "+01:00" then
            "central european time (UTC+1)"
        else
            "central european summertime (UTC+2)"
        end;
    let content := "<style>
    table {
        background-color: #999;
        border: thin solid #999;
        border-radius: 2.3em  2.3em  2.3em  2.3em;
    }
    td,th{
        font-size: medium;
        padding: .1em 1.5em .1em 1.5em;
    }
    td {
        background-color: #ffe;
        font-family: 'Courier New';
        letter-spacing: -0.1em;
        text-align:right;
    }
    th {
        text-align:left;
        background-color: #bba;
    }
    tr:nth-child(odd) td{
          background-color: #ddc;
    }
    tr:nth-of-type(1) th:nth-of-type(1)  {
          border-radius: 2em 0em 0em 0em;
    }
    tr:nth-of-type(1) td:nth-of-type(1)  {
          border-radius: 0em 2em 0em 0em;
    }
    tr:nth-of-type(10) th:nth-of-type(1){
        border-radius: 0em 0em 0em 2em;
        }
    tr:nth-of-type(10) td:nth-of-type(1){
        border-radius: 0em 0em 2em 0em;
        }
    </style>
    
    <table>
        <tr><th>place</th><td>" + place + "</td></tr>
        <tr> <th>gps coordinates</th><td> " + lat + latDir + " ⌖ " + long + longDir + "</td></tr>
        <tr> <th>timestamp</th><td>" + format(timeStamp, "dddd DD.MM.YYYY HH:mm", "en") + "</td></tr>
        <tr> <th>time zone</th><td>" + resultSoWi + "</td></tr>
        <tr> <th>sunrise and sunset</th><td>&uarr; " + sunrise + " " + sunset + "&darr;</td></tr>
        <tr> <th>day length</th><td>" + outputDayLengthToday + "</td></tr>
        <tr> <th>timedifference to yesterday</th><td>" + outputDayDiff + "</td></tr>
        <tr> <th>moon phasis</th><td>" + display + "</td></tr>
        <tr> <th>luminated surface of moon</th><td>" + outputLunarPhasePercent + "</td></tr>
        <tr> <th>moon orbit</th><td>" + outputLunarPhaseGrade + "</td></tr>
    </table>
    ";
    html(content)
    
    • mirko3
    • vor 2 Jahren
    • Gemeldet - anzeigen

    ...Zeile 4:

    let timeStamp := now();
    

Content aside

  • 5 „Gefällt mir“ Klicks
  • vor 8 MonatenZuletzt aktiv
  • 5Antworten
  • 217Ansichten
  • 6 Folge bereits