Anzeige:
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 15 von 18

Thema: komplexe Berechnungen (Gaußsche Osterformel)

  1. #1
    Registrierter Benutzer
    Registriert seit
    Dec 2018
    Beiträge
    15

    komplexe Berechnungen (Gaußsche Osterformel)

    Hallo zusammen,
    ich nutze eine Linux-Maschine "nur" als Server. Soll heißen, dass es keine/kaum interaktive Benutzung gibt.
    Für mehrere Programmabläufe ist es wichtig zu prüfen, ob der heutige oder gestrige Tag ein Feiertag ist/war.
    Dabei geht es vor allen Dingen um die beweglichen Feiertage (Ostern, Pfingsten, aber auch der Buß- und Bettag - Sachsen).
    Mit der Gaußschen Osterformel kann ich den Ostersonntag berechnen und von da die anderen Feiertage im ersten Halbjahr.
    Mit ein paar anderen Berechnungen den Buß- und Bettag.
    Allerdings ist die Osterformel sehr komplex. Mit Mod(Rest) und Div(Ganzzahl) komme ich da ganz schnell an die Grenzen in einer Bash-Shell.
    Gibt es eine Lösung, wie ich das in einer Bash-Shell berechnen kann?
    Vielleicht gibt es ja auch schon ein fertiges Konzept.
    Gefunden habe ich hier Forum Hinweise auf bc. Aber das ist ja nun sehr rudimentär. Wenn ich es richtig gesehen habe.

    Danke und allen einen guten Rutsch ins Jahr 2019

    Thomas

    SuSE-Linux Version 4.12.14-lp150.12.28-default
    Geändert von Thomas220 (31.12.18 um 07:16 Uhr)

  2. #2
    Registrierter Benutzer
    Registriert seit
    Dec 2003
    Ort
    Dettenhausen
    Beiträge
    22.054
    "Fertig" als Binary wüsste ich direkt nichts, wobei es einige Kalender-Programme auch für die Konsole gibt - welche davon evtl. für Dich tauglich sind müsstest Du selbst entsprechend prüfen / testen.

    Halbfertig kennt https://www.google.com/search?client...bash+feiertage einiges, da findet man z.B. http://www.wernerflamme.net/doku.php?id=comp:ftagebash drunter, mit leicht abgewandelten Suchbegriffen auch sowas wie https://calumoth.de/wordpress/php-ka...berechnen-103/ - und ja, mit der Bash alleine wird das eher gruselig, aber wenn man schon solche Wünsche hat spricht ja sicherlich auch nichts gegen eine Lösung in einer anderen Sprache - und da das ein gern genommenes Programmier-Übungs-Beispiel ist findet sich in fast jeder Sprache eine mehr oder weniger fertige Implementierung.

    ... aber vielleicht stellst Du ein wenig genauer dar, was Du denn gerne genau wie hättest / wie Deine Anforderungen sind / ...
    Ich bin root - ich darf das.

  3. #3
    Registrierter Benutzer Avatar von ThorstenHirsch
    Registriert seit
    Nov 2002
    Beiträge
    6.556
    Ostern hatten wir schon mal hier berechnet, aber in C statt in der Bash. Und wie man in diesem Thread sieht, ist die Formel nicht perfekt.

    Wie wär's, wenn Du in der Bash einen Kalender im Internet abfragst? Beispiel: https://www.calendarindex.com/api-documentation
    ¡Nuestro amigo... el Computador!

  4. #4
    Registrierter Benutzer
    Registriert seit
    Jan 2008
    Beiträge
    2.551
    Zitat Zitat von Thomas220 Beitrag anzeigen
    Allerdings ist die Osterformel sehr komplex. Mit Mod(Rest) und Div(Ganzzahl) komme ich da ganz schnell an die Grenzen in einer Bash-Shell.
    Gibt es eine Lösung, wie ich das in einer Bash-Shell berechnen kann?
    Für die beiden Funktionen und andere kann ich Dir den Ausdruck "(( C-Ausdruck ))" vorschlagen, z.B.

    Code:
    a=27; echo $((a / 4)) # entspricht DIV(27,4) 
    6
    a=27; echo $((a % 4)) # entspricht MOD(27,4)
    3
    Wichtig: Variablen werden im Ausdruck OHNE "$" referenziert.

    Auch mit let/expr möglich:

    Code:
    a=27; let b="a / 4"; echo $b
    6
    a=27; let b="a % 4"; echo $b
    3
    Siehe auch hier

    Wie die Ausdrücke nun genau abgearbeitet werden entzieht sich leider meiner Kenntnis...

    Grüße an Alle und einen guten Rutsch...
    Geändert von Aqualung (01.01.19 um 11:13 Uhr)

  5. #5
    Registrierter Benutzer
    Registriert seit
    Dec 2018
    Beiträge
    15
    Hallo zusammen,

    hate gestern schon mal eine Antwort gegeben, in der ich mich bei allen bedankte.
    Ist aber weg :-(

    Dann auf diesem Weg nochmals vielen Dank an alle.

    Ich werde das eine oder andere testen (auf www.calendarindex.com war ich schon) und mich dann melden.

    Allen ein gesundes neues Jahr

    Thomas

  6. #6
    Registrierter Benutzer
    Registriert seit
    Dec 2018
    Beiträge
    15
    Hallo zusammen,

    die Lösung, die Aqualung vorschlug ist für mich die beste.
    Die Fleißarbeit ist erledigt.

    Um das Ergebnis der Osterformel anwenden zu können, ist es notwendig, dass ich mit dem Datum in der Shell rechne.
    Habe schon einige Beispiele hier gesehen. Jedoch beziehen sich fast alle auf den Vortag (date -d '-1 day' +%Y%m%d)

    Ich will aber berechnen, welches Datum der 306te Tage vor dem 31.12.2019 (z. Bsp.) ist.
    Habe da schon ein bisschen probiert, aber ich kriege es nicht hin:
    Code:
    em=`date -d 2019-12-31 306 day ago +%Y%m%d`
    Die Variable 'em' ist nur eine Wildcard.
    Code:
    date: extra operand ‘+%Y’
    Try 'date --help' for more information.
    date: extra operand ‘day’
    Try 'date --help' for more information.
    Und das hier:
    Code:
    em=`date -d 2019-12-31` '-306 day' +%Y%m%d
    brachte das Ergebnis:
    Code:
    date: extra operand ‘+%Y’
    Try 'date --help' for more information.
    ./feiertage.sh: line 16: -306 day: command not found
    Wie muss ich das richtig machen?

    Danke
    Thomas

  7. #7
    Universaldilletant Avatar von fork
    Registriert seit
    Dec 2001
    Ort
    Frankfurt/Main
    Beiträge
    1.175
    Zitat Zitat von Thomas220 Beitrag anzeigen
    Code:
    em=`date -d 2019-12-31 306 day ago +%Y%m%d`
    Code:
    date: extra operand ‘+%Y’
    Try 'date --help' for more information.
    date: extra operand ‘day’
    Try 'date --help' for more information.
    Quoting Fehler...

    So würde es funktionieren:

    em=`date -d "2019-12-31 306 day ago" +%Y%m%d`

    Und das hier:
    Code:
    em=`date -d 2019-12-31` '-306 day' +%Y%m%d
    brachte das Ergebnis:
    Code:
    date: extra operand ‘+%Y’
    Try 'date --help' for more information.
    ./feiertage.sh: line 16: -306 day: command not found
    Das wäre das:
    em=`date -d "2019-12-31 -306 day" +%Y%m%d`

    Das Argument "2019-12-31 - 306 days" ist nur ein Argument und muß deswegen geschützt werden, da sonst die Leerzeichen dafür sorgen, dass es in mehrere Argumente aufgebrochen wird und damit eine inkorrekte Syntax darstellt.

    Und ansonsten vergiß die Backticks `...` sondern verwende lieber $(...). Die Backticks sind zum einen leichter mit Hochkommata '...' oder normalen Anführungszeichen "..." zu verwechseln und zum anderen kann man die nur sehr häßlich verschachteln.

    Also mein Vorschlag ist der:

    Code:
    em="$(date -d "2019-12-31 - 306 days" '+%Y%m%d')"
    Das bedeutet, dass sowohl die Datumsbezeichnung (2019-12-31 - 306 days) als auch die Formatzeichenkette(+%Y%m%d) als auch der ganze Variableninhalt(alles auf der rechten Seite des =) nach der Ausführung von `date` geschützt wird, um mögliche Interpretationen durch die Shell zu vermeiden sowie die als Inhalt zu übergebenden Leerzeichen zu schützen.
    Geändert von fork (02.01.19 um 15:12 Uhr)

  8. #8
    Registrierter Benutzer
    Registriert seit
    Dec 2018
    Beiträge
    15

    Wink

    Hallo fork,

    vielen Dank für die schnelle Hilfe.
    Habe Deinen Rat befolgt und mich der letzten Formel bemächtigt.
    Nun klappt es auch mit dem Datum:
    Code:
    Ostersonntag - 2020-04-12
    Ostersonntag - 2019-04-21
    Danke der Formel kann ich nun die anderen beweglichen Feiertag des ersten Halbjahres berechnen.

    Dann kommt der Buß- und Bettag, was hoffentlich nicht so schwer sein wird.

    Danke
    Thomas

  9. #9
    Registrierter Benutzer
    Registriert seit
    Dec 2018
    Beiträge
    15

    Smile

    Hallo zusammen,
    nochmals vielen Dank an alle. Irgendwo gab es immer einen Denkanstoß, der mich meinem Ziel näher brachte
    Die Shell ist nun fertig. Habe sie als Code hier mit eingefügt, vielleicht kann sie jemand gebrauchen.
    Wie man so eine Datei aus einer anderen aufruft und sich nur das Ergebnis übergeben lässt, weiß ich leider nicht.

    Die vielen 'echos' kann man sicher löschen. Beim Programmieren helfen sie mir ungemein.
    Ich habe bewusst alle Zwischenschritte zur Berechnung drin gelassen. Kann man sicher auch einkürzen.
    Bei der Fehlersuche sind sie aber unverzichtbar. Man wird sonst 'adlig'.

    Bei der Auswahl der Feiertage habe ich mich auf Sachsen beschränkt.
    Aber auch die anderen dürften kein Problem sein.
    Wenn jemand Fehler findet, dann soll sie/er sie bitte NICHT behalten, sondern mir mitteilen.

    Code:
     
       
     1 JAHR=2019                        # zu Testzwecken
      2
      3 JAHR=$(date '+%Y')              # Jahr von heute
      4 Datum=$(date +%Y-%m-%d)         # das heutige Datum
      5
      6 ##############################################################
      7 #variable Feiertage nach der gaussschen Osterformel berechnen#
      8 ##############################################################
      9
     10 a=$((JAHR % 19))  # REST (MOD)
     11 b=$((JAHR % 4))
     12 c=$((JAHR % 7))
     13 k=$((JAHR / 100)) # Ganzzahl (DIV)
     14 p=$(((8*$k+13) / 25))
     15 q=$((k / 4))
     16 M=$(((15+$k-$p-$q) % 30))
     17 d=$(((19*$a+$M) % 30))
     18 N=$(((4+$k-$q) % 7))
     19 e=$(((2*$b+4*$c+6*$d+$N) % 7))
     20 ostern=$((22+$d+$e))                                                    # hier wird die eine wichtige Zahl der Osterformel berechnet
     21 # echo $a, $b, $c, $k, $p, $q, $M, $d, $N, $e, $ostern
     22 abzug=$((305 - $ostern + 1))                                            # wieviel Tage vom letzten Kalendertag (31.12. & $Jahr) enfernt ist der Ostersonntag
     23 ostersonntag="$(date -d "$JAHR-12-31 - $abzug days" '+%Y-%m-%d')"       # Datum vom Ostersonntag
     24 karfreitag="$(date -d "$ostersonntag - 2 days" '+%Y-%m-%d')"            # Ostersonntag -2 Tage = Karfreitag
     25 ostermontag="$(date -d "$ostersonntag + 1 days" '+%Y-%m-%d')"           # Ostersonntag +1 Tag = Ostermontag
     26 maennertag="$(date -d "$ostersonntag + 39 days" '+%Y-%m-%d')"           # Ostersonntag + 39 Tage = Christi Himmelfahrt
     27 pfingstsonntag="$(date -d "$ostersonntag + 49 days" '+%Y-%m-%d')"       # Ostersonntag + 49 Tage = Pfingstsonntag
     28 pfingstmontag="$(date -d "$ostersonntag + 50 days" '+%Y-%m-%d')"        # Ostersonntag + 50 Tage = Pfingstmontag
     29 fronleichnam="$(date -d "$ostersonntag + 60 days" '+%Y-%m-%d')"         # Ostersonntag + 60 Tage = Fronleichnam
     30
     31 echo Ostersonntag - $ostersonntag
     32 echo Karfreitag - $karfreitag
     33 echo Ostermontag - $ostermontag
     34 echo Maennertag - $maennertag
     35 echo Pfingstsonntag - $pfingstsonntag
     36 echo Pfingstmontag - $pfingstmontag
     37 echo Fronleichnam - $fronleichnam
     38
     39 ############################
     40 #Buss- und Bettag berechnen#
     41 ############################
     42
     43 Datum1=$(date -d "$JAHR-12-25" '+%Y-%m-%d')                                     # Datum des 25.12. & $JAHR
     44         WT=$(date -d "$Datum1" '+%w')                                           # Wochentag des 25.12. & $JAHR
     45         if [ "$WT" == 0 ]                                                       # wenn der 25.12. & $JAHR ein Sonntag ist ($WT=0), dann müssen 7 Tage abgezogen werden
     46         then WT=7                                                               # um zum 4. Advent zu kommen
     47         fi
     48         vierteradvent="$(date -d "$Datum1 - $WT days" '+%Y-%m-%d')"             # Berechnen des 4. Advents = letzter Sonntag vor dem 25.12. & $JAHR
     49         ersteradvent="$(date -d "$vierteradvent - 21 days" '+%Y-%m-%d')"        # 21 Tage vor dem 4. Advent ist der 1. Advent
     50         totensonntag="$(date -d "$ersteradvent -7 days" '+%Y-%m-%d')"           # 1 Sonntag vor dem 1. Advent ist Totensonntag
     51         bundbtag="$(date -d "$totensonntag -4 days" '+%Y-%m-%d')"               # 4 Tage vor dem Totensonntag ist der Buss- und Bettag
     52
     53 neujahr=$(date -d "$JAHR-01-01" '+%Y-%m-%d')
     54 erstmai=$(date -d "$JAHR-05-01" '+%Y-%m-%d')
     55 nft=$(date -d "$JAHR-10-03" '+%Y-%m-%d')
     56 rft=$(date -d "$JAHR-10-31" '+%Y-%m-%d')
     57 alh=$(date -d "$JAHR-11-01" '+%Y-%m-%d')
     58 erstweih=$(date -d "$JAHR-12-25" '+%Y-%m-%d')
     59 zweitweih=$(date -d "$JAHR-12-26" '+%Y-%m-%d')
     60
     61 if [ "$Datum" == "$bundbtag" ] || [ "$Datum" == "$karfreitag" ] || [ "$Datum" == "$maennertag" ] \
     62         || [ "$Datum" == "$pfingstmontag" ] || [ "$Datum" == "$erstmai" ] || [ "$Datum" == "$neujahr" ] \
             || [ "$Datum" == "$nft" ] || [ "$Datum" == "$rft" ] || [ "$Datum" == "$erstweih" ] || [ "$Datum" == "$zweitweih" ]      # vergleiche, ob heute ein Feiertag ist
     64 then
     65         echo "heute ist ein Feiertag"                                           # JA --> Aktion ausführen
     66 else
     67         echo "heute ist kein Feiertag"                                          # NEIN --> Aktion ausführen
     68 fi
     69
     70
     71 echo VierterAdvent - $vierteradvent
     72 echo ErsterAdvent - $ersteradvent
     73 echo TotenSonntag - $totensonntag
     74 echo BundBTag - $bundbtag
     75 echo WT - $WT
    Thomas

  10. #10
    Universaldilletant Avatar von fork
    Registriert seit
    Dec 2001
    Ort
    Frankfurt/Main
    Beiträge
    1.175
    Die vielen 'echos' kann man sicher löschen. Beim Programmieren helfen sie mir ungemein.
    Auf jeden Fall.

    Du kannst Dir auch eine kleine Funktion in dieser Art schreiben, mit der Du die Ausgabebefehle dann drinbleiben können und nur eine Variable geändert werden muss:

    Code:
    #!/bin/bash
    #
    # mein script
    #
    debug_enabled=1
    export debug_enabled
    
    my_debug() {
       if [ $my_debug -eq 1 ] ;then
          echo "$1"
       fi
    }
    
    # Aufruf
    my_debug "Ostersonntag: $ostersonntag"
    Setzt Du später die Variable debug_enabled auf 0 wird keine Ausgabe mehr erzeugt.
    Geändert von fork (03.01.19 um 15:06 Uhr)

  11. #11
    Registrierter Benutzer
    Registriert seit
    Dec 2018
    Beiträge
    15
    Hallo fork,
    vielen Dank für den Hinweis.
    Muss erst mal setzen lassen

    Thomas

  12. #12
    Registrierter Benutzer
    Registriert seit
    Dec 2018
    Beiträge
    15
    Hallo folk,
    nun habe ich das probiert.
    Eigentlich (gibt's eigentlich gar nicht) alles richtig abgetippt, aber er bringt mir folgende Fehlermeldung:
    Code:
    ./feiertage.sh: line 12: [: -eq: unary operator expected
    Kannst Du bitte nochmal drüberschauen.

    Danke
    Thomas

  13. #13
    Universaldilletant Avatar von fork
    Registriert seit
    Dec 2001
    Ort
    Frankfurt/Main
    Beiträge
    1.175
    Sorry. Fehler meinerseits(Variablenname) war falsch. Die Variable muss natürlich heißen debug_enabled und nicht my_debug ...

    #!/bin/bash
    #
    # mein script
    #
    debug_enabled=1
    export debug_enabled

    my_debug() {
    if [ $debug_enabled -eq 1 ] ;then
    echo "$1"
    fi
    }

    # Aufruf
    my_debug "Ostersonntag: $ostersonntag"

  14. #14
    Registrierter Benutzer
    Registriert seit
    Dec 2018
    Beiträge
    15
    Hallo folk,

    habe es gefunden:

    Code:
    #!/bin/bash
    #
    # mein script
    #
    my_debug=1
    export my_debug
    
    my_debug() {
       if [ $my_debug -eq 1 ] ;then
          echo "$1"
       fi
    }
    
    # Aufruf
    my_debug "Ostersonntag: $ostersonntag"
    Trotzdem vielen Dank.

    Thomas

  15. #15
    Registrierter Benutzer
    Registriert seit
    Dec 2018
    Beiträge
    15
    Hallo folk,
    hatte die Seite nicht aktualisiert und nun meine "Lösung" auch gepostet.
    Ist ja nicht schlimm.

    Danke
    Thomas

Ähnliche Themen

  1. [komplex] Passwort aendern, aber wie
    Von Jaus im Forum Linux Allgemein
    Antworten: 3
    Letzter Beitrag: 21.12.10, 12:31
  2. Hoffentlich richtig hier: USB filerecovery - komplex.
    Von me-$-on im Forum stationäre Hardware
    Antworten: 8
    Letzter Beitrag: 24.04.08, 19:29
  3. Routing komplex
    Von Mister.Sax im Forum Router und Netzaufbau
    Antworten: 15
    Letzter Beitrag: 10.08.06, 08:42
  4. Möchte AVI umkonvertieren. Transcode zu komplex :(
    Von qeldroma75 im Forum Fernsehen
    Antworten: 3
    Letzter Beitrag: 10.02.04, 14:13

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •