Ankündigung

Einklappen
Keine Ankündigung bisher.

Kalenderberechnungen ( Osterformel )

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    Kalenderberechnungen ( Osterformel )

    Hallo zusammen,

    bin gerade dabei die "Osterformel" für die beweglichen Feiertage im eibpc
    abzubilden - im Grundgerüst auch fertig.
    Zur Vereinfachung waere eine Funktion die mir die aktuelle Anzahl
    Tage ( ähnlich Excel ) geben wuerde hilfreich, damit man eleganter die beweglichen Feiertage rechnen kann.
    => hat hier jemand einen Tipp ( m.W. kann ich mit dem Datentyp D24 von KNX nicht rechnen !? ).

    Gruss Wolfgang

    PS: Ziel ist u.a. eine Funktion, die mir auswertet ob gerade Feiertag ist
    ( eine feste Hinterlegung möchte ich nicht ... )
    FB_Addon_TelNo{ height:15px !important; white-space: nowrap !important; background-color: #0ff0ff;}
    ETS 6.2 EibPC V3.x

    #2
    Zitat von wetronic Beitrag anzeigen
    Zur Vereinfachung waere eine Funktion die mir die aktuelle Anzahl
    Tage ( ähnlich Excel ) geben wuerde hilfreich, damit man eleganter die beweglichen Feiertage rechnen kann.
    Was meinst Du mit Anzahl Tage? Du willst wissen, wieviel Tage des Jahres bereits verstrichen sind?
    Skizzenhaft:
    Datum=convert(setdate(),$$)
    Monat=split(...)
    Tag=split(...)
    Aber so genau verstehe ich das Ziel noch nicht
    offizielles Supportforum für den Enertex® EibPC: https://knx-user-forum.de/eibpc/
    Enertex Produkte kaufen

    Kommentar


      #3
      Gute Sammlung von Algorithmen ist hier zu finden.

      Einzelteile kannst Du hier kopieren:

      [highlight=epc]
      /////////////////////////////////////////////////////////////////////////////
      //
      // Aktuelle Systemzeit ermitteln, sollte gleich zu Beginn im Programm stehen,
      // damit die Zeit für nachfolgende Operationen bereit steht
      //
      :begin UnixTime( utResult)
      :info $Aktuelle Werte für Zeit und Datum ermitteln und als UnixTime zurückgeben$
      :shortinfo $Aktuelle Werte für Zeit und Datum ermitteln und als UnixTime zurückgeben$
      :var date@
      date@ = convert(setdate(),$$)
      utYear = convert( split( date@, 6u16, 10u16), 0s32)
      utMonth = convert( split( date@, 3u16, 4u16), 0s32)
      utDay = convert( split( date@, 0u16, 1u16), 0s32)
      utHour = convert( hour(), 0s32 )
      utMinute = convert( minute(), 0s32)
      utSecond = convert( second(), 0s32)

      if change(date@) then {
      ToUnixTime( utYear, utMonth, utDay, utHour, utMinute, utSecond, utResult )
      } endif

      :end

      /////////////////////////////////////////////////////////////////////////////
      //
      // Nachruesten der Funktion Day of Month
      // convert(setdate(),$$) ergibt etwas in der Art dd.mm.yyyy als String
      // da der day of week 0 basierend ist, muß hier 1 subtrahiert werden
      :begin dayofmonth()
      :info $Aktuellen Tag des Monats ermitteln [0..30]$
      :shortinfo $gibt den aktuellen Tag des Monats zurück$
      :return convert( split( convert(setdate(),$$), 0u16, 1u16), 0s32) - 1s32
      :end
      [/highlight]

      Gruß,
      Bernd

      Kommentar


        #4
        Hoi

        Die beweglichen Feiertage berechnen sich als als tageweise Abweichung von Ostern.
        Das Heisst: Ostern plus x Tage ist Pfingsten usw.

        Feiertag Differenz zu Ostern Formel
        Rosenmontag - 48
        Fastnacht - 47
        Aschermittwoch - 46
        Karfreitag - 2
        Ostersonntag
        Ostermontag + 1
        Himmelfahrt + 39
        Pfingstsonntag + 49
        Pfingstmontag + 50
        Fronleichnam + 60
        Grüsse Bodo
        Fragen gehören ins Forum, und nicht in mein Postfach;
        EibPC-Fan; Wiregate-Fan; Timberwolf-Fan mit 30x 1-Wire Sensoren;

        Kommentar


          #5
          Hallo,

          @Bodo: die Berechnung ist mir klar - und genau diese Additionen
          will ich - elegant - ausfuehren

          Generell: in Excel gibt es Funktin DATWERT, diese formt den Datumsstring in
          eine Tageszahl ( ab 1900 ? ) um. Dann muss man nur den Ostertag
          ( mit DATWERT ) umwandeln und die entsprechenden Tage für
          Himmelfahrt etc. wieder addieren - anschliessend wieder in
          Datumsstring wandeln.

          Mit Unixtime kann man den Weg auch gehen, wenn man ggf. die Zeit entfernt ...
          FB_Addon_TelNo{ height:15px !important; white-space: nowrap !important; background-color: #0ff0ff;}
          ETS 6.2 EibPC V3.x

          Kommentar


            #6
            Das komplette Makro findet sich in den Libraries von Enertex: EnertexCodingWettbewerb.lib

            Gruß,
            Bernd

            Kommentar


              #7
              Ich habe das Thema schon vor einiger Zeit umgesetzt, habe aber noch irgendeinen Bug in der Berechnung.

              Das Datum weicht bei meinen Tests in der Regel um 1-2 Tage ab.

              Der große Stolperstein bei der Umsetzung war, dass sich die mod() Funktion nicht gemäß Handbuch verhält.

              Vielleicht findet ja hier jemand den Fehler schneller als ich.

              Viele Grüße

              Michael


              [highlight=epc]
              //
              // -----------------------------------------------------------------------------------------------------------
              // Berechnung der Feiertage
              // -----------------------------------------------------------------------------------------------------------
              //

              // Berechnung des Ostersonntags mit der Gaußschen Osterformel für den gregorianische Kalender (ab 1583)
              Karfreitag = $$
              Ostersonntag = $$
              Ostermontag = $$

              // Berechnung der Säkularzahl K
              Osterformel_K = convert(AktuellesJahr, 0f32) / 100f32

              // Berechnung der säkularen Mondschaltung M
              Osterformel_M = 15f32 + (3f32 * Osterformel_K + 3f32) / 4f32 - (8f32 * Osterformel_K + 13f32) / 25f32

              // Berechnung der säkularen Sonnenschaltung S
              Osterformel_S = 2f32 - (3f32 * Osterformel_K + 3f32) / 4f32

              // Berechnung des Mondparameters A
              // Osterformel_A = mod(convert(AktuellesJahr, 0f16), 19f16) wäre die korrekte Formel, aber mod(Xf16,Xf16) hat einen Bug
              Osterformel_A = convert(mod(convert(AktuellesJahr, 0u16), 19u16), 0f32)

              // Berechnung des Keims für den ersten Vollmond im Frühling D
              // Osterformel_D = mod((19f32 * Osterformel_A + Osterformel_M), 30f32) wäre ohne Bug die korrekte Formel
              Osterformel_D1 = (19f32 * Osterformel_A + Osterformel_M) / 30f32
              Osterformel_D2 = convert((19s16 * convert(Osterformel_A, 0s16) + convert(Osterformel_M, 0s16)) / 30s16, 0f32)
              Osterformel_D = (Osterformel_D1 - Osterformel_D2) * 30f32

              // Berechnung der kalendarischen Korrekturgröße R
              Osterformel_R = Osterformel_D / 29f32 + (Osterformel_D / 28f32 - Osterformel_D / 29f32) * (Osterformel_A / 11f32)

              // Berechnung der Ostergrenze OG
              Osterformel_OG = 21f32 + Osterformel_D - Osterformel_R

              // Berechnung des ersten Sonntag im März SZ
              // Osterformel_SZ = mod(7f32 - (convert(AktuellesJahr, 0f32) + convert(AktuellesJahr, 0f32) / 4f32 + Osterformel_S), 7f32) wäre ohne Bug die korrekte Formel
              Osterformel_SZ1 = (7f32 - convert(AktuellesJahr, 0f32) + convert(AktuellesJahr, 0f32) / 4f32 + Osterformel_S) / 7f32
              Osterformel_SZ2 = convert((7s16 - convert(AktuellesJahr, 0s16) + convert(AktuellesJahr, 0s16) / 4s16 + convert(Osterformel_S, 0s16)) / 7s16, 0f32) - 1f32
              Osterformel_SZ = (Osterformel_SZ1 - Osterformel_SZ2) * 7f32

              // Berechnung der Entfernung des Ostersonntags von der Ostergrenze (Osterentfernung in Tagen)
              // Osterformel_OE = mod(7f32 - (Osterformel_OG - Osterformel_SZ), 7f32) w√§re ohne Bug die korrekte Formel
              Osterformel_OE1 = (7f32 - (Osterformel_OG - Osterformel_SZ)) / 7f32
              Osterformel_OE2 = convert((7s16 - (convert(Osterformel_OG, 0s16) - convert(Osterformel_SZ, 0s16))) / 7s16, 0f32) - 1f32
              Osterformel_OE = (Osterformel_OE1 - Osterformel_OE2) * 7f32

              // Berechnung des Datum des Ostersonntag als Märzdatum (32. März = 1. April usw.)
              Osterformel_OS = convert(Osterformel_OG + Osterformel_OE, 0u08)
              if Osterformel_OS <= 31u08 then \\
              Ostersonntag = convert(Osterformel_OS, $$) + $.03.$ + AktuellesJahr \\
              else \\
              Ostersonntag = convert(Osterformel_OS - 31u08, $$) + $.04.$ + AktuellesJahr \\
              endif

              // Berechnung des Datum des Ostermontag als Märzdatum
              Osterformel_OM = Osterformel_OS + 1u08
              if Osterformel_OM <= 31u08 then \\
              Ostermontag = convert(Osterformel_OM, $$) + $.03.$ + AktuellesJahr \\
              else \\
              Ostermontag = convert(Osterformel_OM - 31u08, $$) + $.04.$ + AktuellesJahr \\
              endif

              // Berechnung des Datum des Karfreitag als Märzdatum
              Osterformel_KF = Osterformel_OS - 2u08
              if Osterformel_KF <= 31u08 then \\
              Karfreitag = convert(Osterformel_KF, $$) + $.03.$ + AktuellesJahr \\
              else \\
              Karfreitag = convert(Osterformel_KF - 31u08, $$) + $.04.$ + AktuellesJahr \\
              endif
              [/highlight]

              Kommentar


                #8
                Ich weiss noch von keinem Makro, das die Osterformel zuverlässig umsetzt, deshalb habe ich mich auf die festliegenden Feiertage beschränkt und folgendes versucht:

                Feiertag=AUS

                if dayofweek()==SONNTAG or month(1,1) or month(6,1) or month(1,5) or month(3,10) or month(1,11) or month(25,12) or month(26,12) then Feiertag=EIN
                else Feiertag=AUS endif

                Leider funzt das auch nicht, nach Neu-laden des EibPC ist Feiertag immer ein. Was mache ich falsch?

                Kommentar


                  #9
                  Moin,

                  Zitat von Handbuch
                  Der Ausgang ist 1b01, wenn das Datum erreicht oder bereits verstrichen ist. Liegt das Datum vor dem eingestellten Wert, geht der Ausgang auf 0b01. Mit dem Beginn eines neuen Jahres (Januar, 1) geht der Ausgang auf 0b01, bis der Monat und Tag den eingestellten Wert erreichen.
                  ergo wenn Du irgendwo alleine month(1,1) stehen hast, dann geht es am Jahresanfang auf EIN und das war's...

                  [highlight=epc]
                  Feiertag = dayofweek()==SONNTAG or \\
                  (month(1,1) and !month(2,1)) or \\
                  (month(6,1) and !month(7,1)) or \\
                  (month(3,10) and !month(4,10)) or \\
                  (month(1,11) and !month(2,11)) or \\
                  (month(25,12) and !month(27,12))[/highlight]

                  Gruß,
                  Bernd

                  Kommentar


                    #10
                    Danke für die rasche Antwort, ich hatte schon sowas geahnt. Diese Version funzt nun (ohne if/then hat der Compiler gemeckert):

                    Code:
                    if dayofweek()==SONNTAG or \\
                        (month(1,1) and !month(2,1)) or \\
                            (month(6,1) and !month(7,1)) or  \\
                            (month(3,10) and !month(4,10)) or \\
                            (month(1,11) and !month(2,11)) or \\
                            (month(25,12) and !month(27,12)) \\
                    then Feiertag=EIN else Feiertag=AUS endif

                    Kommentar


                      #11
                      Hallo,

                      danke nochmals fuer das rege Interesse. Ich bin nun so weit, dass ich
                      den Ostertag stabil berechnen kann und einen Satz Funktionen habe
                      mit denen ich ein Tagesdatum auf eine relative Tageszahl umrechnen kann
                      ( und wieder zurueck ). Damit kann ich dann gut die restlichen Tage bestimmen ( angelehnt an das Makro mit unixtime aus dem CodingWettbewerb ).
                      Anschliessend werde ich die Feiertage im Flash ablegen und diese
                      kurz nach Mitternacht ueber eine Schleife mit dem Tagesdatum vergleichen => Flag FEIERTAG.

                      Sobald alles stabil, melde ich mich wieder ...

                      Gruss

                      Wolfgang
                      ETS 6.2 EibPC V3.x

                      Kommentar


                        #12
                        Zitat von Kahler Beitrag anzeigen
                        Danke für die rasche Antwort, ich hatte schon sowas geahnt. Diese Version funzt nun (ohne if/then hat der Compiler gemeckert):
                        Gut,
                        ich würde das Rücksetzen wie beim Beispiel mit dem Geburstagskalender im Handbuch folgt machen:
                        [highlight=epc]
                        if dayofweek()==SONNTAG then Feiertag=EIN endif
                        if month(1,1) then Feiertag=EIN endif
                        if month(6,1) then Feiertag=EIN endif
                        // ... usw
                        if htime(23,59,59) or systemstart() then Feiertag=AUS endif
                        [/highlight]
                        Dann würde für jeden Feiertag auch immer ein Impuls in der Variable generiert werden.
                        offizielles Supportforum für den Enertex® EibPC: https://knx-user-forum.de/eibpc/
                        Enertex Produkte kaufen

                        Kommentar


                          #13
                          Zitat von wetronic Beitrag anzeigen
                          .
                          Anschliessend werde ich die Feiertage im Flash ablegen und diese
                          kurz nach Mitternacht ueber eine Schleife mit dem Tagesdatum vergleichen => Flag FEIERTAG.
                          hm, wieso die im Flash ablegen?
                          offizielles Supportforum für den Enertex® EibPC: https://knx-user-forum.de/eibpc/
                          Enertex Produkte kaufen

                          Kommentar


                            #14
                            Hallo Michael,

                            im Flash, da diese Werte statisch sind und nur zum Jahreswechsel
                            bestimmt werden. Weiterhin kann ich auf den Flash indexiert mit einer
                            Schleife zugreifen - gefaellt mir besser als ein PseudoArray mittels c1400
                            String zu bauen:
                            Im Flash lege ich jeweils einen String wie folgt ab: "xDD.MM" und "x" kennzeichnet G = gesetzlich, B = Geburtstag, F = allg. Feiertag ...

                            Nach Mitternacht wird dann das neue Tageadatum gegen den Flash
                            geprueft und ich habe dann ein Flag: Art des Feiertags ...

                            ( oder kann man inzwischen Arrays klassisch abbilden ? )

                            Gruss

                            Wolfgang
                            ETS 6.2 EibPC V3.x

                            Kommentar


                              #15
                              Zitat von wetronic Beitrag anzeigen
                              Im Flash lege ich jeweils einen String wie folgt ab: "xDD.MM" und "x" kennzeichnet G = gesetzlich, B = Geburtstag, F = allg. Feiertag ...
                              Wieso denn dann im Flash abspeichern? Der String hat es dann doch schon. Da bringt das Abspeichern nicht viel. Oder was versteh ich nicht?
                              offizielles Supportforum für den Enertex® EibPC: https://knx-user-forum.de/eibpc/
                              Enertex Produkte kaufen

                              Kommentar

                              Lädt...
                              X