Seite 1 von 1

[V4.5 IP1] Custom Logik: Ostersonntag berechnen

Verfasst: Do Nov 28, 2024 8:31 am
von jensgulow
Um Feiertage im Jahr zu berechnen ist es für etliche Daten notwendig zu wissen welches Datum der Ostersonntag hat (und welcher Tag des Jahres dies ist).
Hier eine Custom-Logik, welche nach der einfachen Gauß-Osterformel das Datum berechnet.
Die Ausnahme Ostersonntag berechnet 26.4. -> Korrektur auf 19.4. ist hier nicht berücksichtigt (könnte aber sicher noch eingebaut werden).
Vielleicht hat jemand Verwendung.

Code: Alles auswählen

/**
 * =======================================
 * Calc Easter - Datum Ostersonntag berechnen
 * =======================================
 * a = Jahr mod 4
 * b = Jahr mod 7
 * c = Jahr mod 19
 * d = (19c + 24) mod 30
 * e = (2a + 4b + 6d + 5) mod 7
 * (f = (c+11d+22e)/451) -> das lassen wir weg
 * (Den Ostersonntag ermitteln Sie daraus wie folgt: 22+d+e-7f) -> Vereinfachung siehe nächste Zeile
 * OS=22+d+e
 * Ist dieses Ergebnis größer als 31, so liegt Ostern im April. Dann muss folgende Formel für die Berechnung des Ostersonntag angewandt werden= d+e-9.
 * Eine Besonderheit hat Gauß selbst in seiner Formel gefunden: Ergibt die Rechnung den 26. April als Osterdatum, müssen Sie stattdessen den 19. April setzen.
 * -> Diese Ausnahme ist hier nicht berücksichtigt!
 * ACHTUNG: "mod" ist als Rechenoption nicht verfügbar -> deshalb "Umweg" über "rint" !
 
 * =================================================================================
 * Day of Year: Tageszahl des Ostersonntag - wichtig für Berechnungen einiger anderer Feiertage
 * =================================================================================
 * in Anlehnung an diese Formeln um gesetzt mit "rint" statt "floor":
 * N1 = floor(275 * month / 9)
 * N2 = floor((month + 9) / 12)
 * N3 = (1 + floor((year - 4 * floor(year / 4) + 2) / 3))
 * N = N1 - (N2 * N3) + day - 30
 */
{ 
    "Level": [ 

	// interne Level
	["$Year","integer",0],
	["$Month","integer",0],
	["$Day","integer",0],
	["$DOY","integer",0],

	["$Year%4","float",0.0],
	["$Year%7","float",0.0],
	["$Year%19","float",0.0],

	["$_a","integer",0],
	["$_b","integer",0],
	["$_c","integer",0],
	["$_d_pre","float",0.0],
	["$_d","integer",0],
	["$_e_pre","float",0.0],
	["$_e","integer",0],
	["$_f","integer",0],
	["$_OS","integer",0],
	["$_OS_apr","integer",0],
	["$April","bool",false],

	["$Formula_Year%4","string","X1/4"],
	["$Formula_Yearmod4","string","(X1-rint(X1-0.5))*4"], // Ergebnis ist $_a
	["$Formula_Year%7","string","X1/7"],
	["$Formula_Yearmod7","string","(X1-rint(X1-0.5))*7"], // Ergebnis ist $_b
	["$Formula_Year%19","string","X1/19"],
	["$Formula_Yearmod19","string","(X1-rint(X1-0.5))*19"], // Ergebnis ist $_c

	// X1=$_c
	["$Formula_d_pre","string","((19*X1)+24)/30"], // Ergebnis ist $_d_pre
	// X1=$_d_pre
	["$Formula_d","string","(X1-rint(X1-0.5))*30"], // Ergebnis ist $_d

	// X1=$_a; X2=$_b; X3=$_d
	["$Formula_e_pre","string","((2*X1)+(4*X2)+(6*X3)+5)/7"], // Ergebnis ist $_e_pre
	// X1=$_e_pre
	["$Formula_e","string","(X1-rint(X1-0.5))*7"], // Ergebnis ist $_e

	// X1=$_d; X2=$_e
	["$Formula_OS","string","22+X1+X2"], // Ergebnis ist $_OS

	//X1=$_OS
	["$Formula_April","string","(X1>31)?4:3"], // Ergebnis ist $Month
	["$Formula_April_bool","string","(X1>31)?1:0"], // Ergebnis ist $April

	//X1=$_d; X2=$_e
	["$Formula_OS_apr","string","X1+X2-9"], // Ergebnis ist $_OS_apr
	
	["$N1","integer",0],	
	["$N2","integer",0],	
	["$N3","integer",0],	

	// X1=$Month
	["$Formula_N1","string","rint((275*X1/9)-0.5)"], // Ergebnis ist  $N1
	
	// X1=$Month
	["$Formula_N2","string","rint(((X1+9)/12)-0.5)"], // Ergebnis ist  $N2

	// X1=$Year
	["$Formula_N3","string","(1+rint(((X1-(4*rint((X1/4)-0.5))+2)/3)-0.5))"], // Ergebnis ist  $N3

	// X1=$N1; X2=$N2; X3=$N3; X4=$Day
	["$Formula_DOY","string","X1-(X2*X3)+X4-30"], // Ergebnis ist $DOY
	
	["$VAR<Inhibit?>","bool",false]

    ], 
    "Module": [

	// a = Jahr mod 4
	["CalcFormula",["$Year"], "$Year%4", "$Formula_Year%4"],
	["CalcFormula",["$Year%4"], "$_a", "$Formula_Yearmod4"],

	// b = Jahr mod 7
	["CalcFormula",["$Year"], "$Year%7", "$Formula_Year%7"],
	["CalcFormula",["$Year%7"], "$_b", "$Formula_Yearmod7"],

	// c = Jahr mod 19
	["CalcFormula",["$Year"], "$Year%19", "$Formula_Year%19"],
	["CalcFormula",["$Year%19"], "$_c", "$Formula_Yearmod19"],
	
	// d = (19c + 24) mod 30
	["CalcFormula",["$_c"], "$_d_pre", "$Formula_d_pre"],
	["CalcFormula",["$_d_pre"], "$_d", "$Formula_d"],

	// e = (2a + 4b + 6d + 5) mod 7
	["CalcFormula",["$_a","$_b","$_d"], "$_e_pre", "$Formula_e_pre"],
	["CalcFormula",["$_e_pre"], "$_e", "$Formula_e"],
	
	// OS = 22+d+e
	["CalcFormula",["$_d","$_e"], "$_OS", "$Formula_OS"], // -> Tageszahl im März (wenn <=31)
	
	// wenn $OS>31 -> Ostern liegt im April
	["CalcFormula",["$_OS"], "$Month", "$Formula_April"], // -> Monat in dem Ostersonntag liegt
	["CalcFormula",["$_OS"], "$April", "$Formula_April_bool"], // -> April? -> true; März -> false

	// OS_apr = d+e-9
	["CalcFormula",["$_d","$_e","$_f"], "$_OS_apr", "$Formula_OS_apr"], // -> Tageszahl im April

	// Tageszahl des Ostersonntages in Abhängigkeit vom Monat auf den Ausgang schreiben
	["Latch","$_OS_apr","$Day","$April",0],
	["Latch","$_OS","$Day","-$April",0],

	// Jetzt $DOY (Day of Year) berechnen
	["CalcFormula",["$Month"], "$N1", "$Formula_N1"], 
	["CalcFormula",["$Month"], "$N2", "$Formula_N2"], 
	["CalcFormula",["$Year"], "$N3", "$Formula_N3"], 
	["CalcFormula",["$N1", "$N2", "$N3", "$Day"], "$DOY", "$Formula_DOY"] 
    ], 

    "Input": [ 
	["Year", "vierstellige Angabe (hier vom Uhrzeitbaustein empfangen)", "$Year", "ai" ]
    ], 

    "Output": [ 
    ["Tag Ostersonntag","","$Day","c"],
    ["Monat Ostersonntag","","$Month","c"],
    ["Day of Year","","$DOY","c"]	
    ] 
} 
/**Der Schöpfer dieser Custom Logik überträgt die Nutzungsrechte gemäß der TOLL 
("Timberwolf Open Logikblock License") die unter https://wrgt.news/TOLL zum Download zur Verfügung steht. */ 
Calc Easter.jpg

Re: [V4.5 IP1] Custom Logik: Ostersonntag berechnen

Verfasst: Fr Dez 06, 2024 5:26 pm
von jhaeberle
Hallo Jens,

Verbesserungsvorschlag für diese Custom Logik: das Jahr im Code ermitteln und so einen Input und eine weitere Logik eliminieren. Hab ich bei deinen beiden anderen Feiertagslogiken abgeschaut :D

Code: Alles auswählen

/**
 * =======================================
 * Calc Easter - Datum Ostersonntag berechnen
 * =======================================
 * a = Jahr mod 4
 * b = Jahr mod 7
 * c = Jahr mod 19
 * d = (19c + 24) mod 30
 * e = (2a + 4b + 6d + 5) mod 7
 * (f = (c+11d+22e)/451) -> das lassen wir weg
 * (Den Ostersonntag ermitteln Sie daraus wie folgt: 22+d+e-7f) -> Vereinfachung siehe nächste Zeile
 * OS=22+d+e
 * Ist dieses Ergebnis größer als 31, so liegt Ostern im April. Dann muss folgende Formel für die Berechnung des Ostersonntag angewandt werden= d+e-9.
 * Eine Besonderheit hat Gauß selbst in seiner Formel gefunden: Ergibt die Rechnung den 26. April als Osterdatum, müssen Sie stattdessen den 19. April setzen.
 * -> Diese Ausnahme ist hier nicht berücksichtigt!
 * ACHTUNG: "mod" ist als Rechenoption nicht verfügbar -> deshalb "Umweg" über "rint" !
 
 * =================================================================================
 * Day of Year: Tageszahl des Ostersonntag - wichtig für Berechnungen einiger anderer Feiertage
 * =================================================================================
 * in Anlehnung an diese Formeln um gesetzt mit "rint" statt "floor":
 * N1 = floor(275 * month / 9)
 * N2 = floor((month + 9) / 12)
 * N3 = (1 + floor((year - 4 * floor(year / 4) + 2) / 3))
 * N = N1 - (N2 * N3) + day - 30
 */
{ 
    "Level": [ 

	// interne Level
	["$Year","integer",0],
	["$Month","integer",0],
	["$Day","integer",0],
	["$DOY","integer",0],

	["$Year%4","float",0.0],
	["$Year%7","float",0.0],
	["$Year%19","float",0.0],

	["$_a","integer",0],
	["$_b","integer",0],
	["$_c","integer",0],
	["$_d_pre","float",0.0],
	["$_d","integer",0],
	["$_e_pre","float",0.0],
	["$_e","integer",0],
	["$_f","integer",0],
	["$_OS","integer",0],
	["$_OS_apr","integer",0],
	["$April","bool",false],

	["$Formula_Year%4","string","X1/4"],
	["$Formula_Yearmod4","string","(X1-rint(X1-0.5))*4"], // Ergebnis ist $_a
	["$Formula_Year%7","string","X1/7"],
	["$Formula_Yearmod7","string","(X1-rint(X1-0.5))*7"], // Ergebnis ist $_b
	["$Formula_Year%19","string","X1/19"],
	["$Formula_Yearmod19","string","(X1-rint(X1-0.5))*19"], // Ergebnis ist $_c

	// X1=$_c
	["$Formula_d_pre","string","((19*X1)+24)/30"], // Ergebnis ist $_d_pre
	// X1=$_d_pre
	["$Formula_d","string","(X1-rint(X1-0.5))*30"], // Ergebnis ist $_d

	// X1=$_a; X2=$_b; X3=$_d
	["$Formula_e_pre","string","((2*X1)+(4*X2)+(6*X3)+5)/7"], // Ergebnis ist $_e_pre
	// X1=$_e_pre
	["$Formula_e","string","(X1-rint(X1-0.5))*7"], // Ergebnis ist $_e

	// X1=$_d; X2=$_e
	["$Formula_OS","string","22+X1+X2"], // Ergebnis ist $_OS

	//X1=$_OS
	["$Formula_April","string","(X1>31)?4:3"], // Ergebnis ist $Month
	["$Formula_April_bool","string","(X1>31)?1:0"], // Ergebnis ist $April

	//X1=$_d; X2=$_e
	["$Formula_OS_apr","string","X1+X2-9"], // Ergebnis ist $_OS_apr
	
	["$N1","integer",0],	
	["$N2","integer",0],	
	["$N3","integer",0],	

	// X1=$Month
	["$Formula_N1","string","rint((275*X1/9)-0.5)"], // Ergebnis ist  $N1
	
	// X1=$Month
	["$Formula_N2","string","rint(((X1+9)/12)-0.5)"], // Ergebnis ist  $N2

	// X1=$Year
	["$Formula_N3","string","(1+rint(((X1-(4*rint((X1/4)-0.5))+2)/3)-0.5))"], // Ergebnis ist  $N3

	// X1=$N1; X2=$N2; X3=$N3; X4=$Day
	["$Formula_DOY","string","X1-(X2*X3)+X4-30"], // Ergebnis ist $DOY
	
	["$VAR<Inhibit?>","bool",false]

    ], 
    "Module": [

    // MODIFICATION Jahr selbst ermitteln
	["Localtime",0,0,0,0,0,0,0, "$Year",0,0,0],

	// a = Jahr mod 4
	["CalcFormula",["$Year"], "$Year%4", "$Formula_Year%4"],
	["CalcFormula",["$Year%4"], "$_a", "$Formula_Yearmod4"],

	// b = Jahr mod 7
	["CalcFormula",["$Year"], "$Year%7", "$Formula_Year%7"],
	["CalcFormula",["$Year%7"], "$_b", "$Formula_Yearmod7"],

	// c = Jahr mod 19
	["CalcFormula",["$Year"], "$Year%19", "$Formula_Year%19"],
	["CalcFormula",["$Year%19"], "$_c", "$Formula_Yearmod19"],
	
	// d = (19c + 24) mod 30
	["CalcFormula",["$_c"], "$_d_pre", "$Formula_d_pre"],
	["CalcFormula",["$_d_pre"], "$_d", "$Formula_d"],

	// e = (2a + 4b + 6d + 5) mod 7
	["CalcFormula",["$_a","$_b","$_d"], "$_e_pre", "$Formula_e_pre"],
	["CalcFormula",["$_e_pre"], "$_e", "$Formula_e"],
	
	// OS = 22+d+e
	["CalcFormula",["$_d","$_e"], "$_OS", "$Formula_OS"], // -> Tageszahl im März (wenn <=31)
	
	// wenn $OS>31 -> Ostern liegt im April
	["CalcFormula",["$_OS"], "$Month", "$Formula_April"], // -> Monat in dem Ostersonntag liegt
	["CalcFormula",["$_OS"], "$April", "$Formula_April_bool"], // -> April? -> true; März -> false

	// OS_apr = d+e-9
	["CalcFormula",["$_d","$_e","$_f"], "$_OS_apr", "$Formula_OS_apr"], // -> Tageszahl im April

	// Tageszahl des Ostersonntages in Abhängigkeit vom Monat auf den Ausgang schreiben
	["Latch","$_OS_apr","$Day","$April",0],
	["Latch","$_OS","$Day","-$April",0],

	// Jetzt $DOY (Day of Year) berechnen
	["CalcFormula",["$Month"], "$N1", "$Formula_N1"], 
	["CalcFormula",["$Month"], "$N2", "$Formula_N2"], 
	["CalcFormula",["$Year"], "$N3", "$Formula_N3"], 
	["CalcFormula",["$N1", "$N2", "$N3", "$Day"], "$DOY", "$Formula_DOY"] 
    ], 

    "Input": [ 
    ], 

    "Output": [ 
    ["Tag Ostersonntag","","$Day","c"],
    ["Monat Ostersonntag","","$Month","c"],
    ["Day of Year","","$DOY","c"]	
    ] 
} 
/**Der Schöpfer dieser Custom Logik überträgt die Nutzungsrechte gemäß der TOLL 
("Timberwolf Open Logikblock License") die unter https://wrgt.news/TOLL zum Download zur Verfügung steht. */ 
Gruß
Jochen

Re: [V4.5 IP1] Custom Logik: Ostersonntag berechnen

Verfasst: Fr Dez 06, 2024 5:54 pm
von jensgulow
Ja, natürlich ist das auch möglich. Ich nehme halt das eingehende Jahr gleich als Trigger.

Re: [V4.5 IP1] Custom Logik: Ostersonntag berechnen

Verfasst: Fr Dez 06, 2024 6:06 pm
von jhaeberle
jensgulow hat geschrieben: Fr Dez 06, 2024 5:54 pm Ja, natürlich ist das auch möglich. Ich nehme halt das eingehende Jahr gleich als Trigger.
Dachte ich mir auch, aber warum dann nicht auch so bei der Adventberechnung?

Gruß
Jochen

Re: [V4.5 IP1] Custom Logik: Ostersonntag berechnen

Verfasst: Fr Dez 06, 2024 6:17 pm
von jensgulow
Die Adventsberechnung wollte ich unbedingt gerne schon wenige Sekunden nach Mitternacht haben - war für einige Logiken so notwendig....

Re: [V4.5 IP1] Custom Logik: Ostersonntag berechnen

Verfasst: Fr Dez 06, 2024 6:32 pm
von jhaeberle
Ok. Sorry, aber das ist mir zu hoch. Würdest du das nicht am leichtesten und sichersten mit einem Cron-Trigger hin bekommen? Bitte, wo ist jetzt bei der Triggerung der Unterschied zwischen der Oster- und der Adventslogik? Warum behandelst du die unterschiedlich?

Re: [V4.5 IP1] Custom Logik: Ostersonntag berechnen

Verfasst: Fr Dez 06, 2024 6:53 pm
von jensgulow
Es war mir zu dem entsprechenden Zeitpunkt die einfachste Lösung - die Logiken sind zu komplett verschiedenen Zeitpunkten entstanden.
Kann ja auch jeder nach seinem Geschmack abändern.
Ein tieferer philosophischer Ansatz steht da nicht dahinter :lol:
Für mich funktioniert es so - also ändere ich da auch nix. ;)