2. Tipps und Tricks  Teil 2  ab 2.2.28  (zurück zu Teil 2 Anfang , Teil 2 Uhr, zu Teil_1 , zu Startseite )

 (zurück zu Teil 2 Uhr ) ccBasic DOW, Sommerzeit bestimmen, usw.

(zurück zu  Datum_berechnen allgemein )

 Datum berechnen Fortsetzung  für Steuerungsgeräte   (13.03.2008, Stand: 19.12.2016)  

DOW  Tag-Nummer in der Woche

Jahrestag  Tag-Nummer im Jahr

Wochennummer im Jahr, Kalenderwoche

        Osterdatum berechnen für Steuerungsgeräte      mit Basic z.B. c-control

                                                                                in Assembler für PIC

Bewegliche Feiertage Rosenmontag, Karfreitag, Himmelfahrt, Pfingsten, Fronleichnam,

Muttertag, Advent, Datum Sommerzeit, Buß- und Bettag mit Osterdatum berechnen

Steuern mit Feiertagsbit  für Heizung, Rollladen und Kirchenglocken

Unterprogramme für feste und bewegliche Feiertage

Weiter zu Tipps und Tricks Teil 3

Zeittakte mit Uhrzeit und TIMER, Wartezeit,

(Schaltuhr siehe Softwarebausteine)

Weiter zu Tipps und Tricks Teil  4

Überschreitung von 32767 beim Rechnen, Begrenzen

Zählen bis 65535 im word, Zahl  0 bis 65535, Anzeigen mit 1 bis 2 Kommastellen

Zahlen über 65535  Zähler, Addition, Multiplikation, Division


2.2.28)   Einfache Berechnung des Wochentages  für 2000 bis 2099

Die erforderliche Konstante KM je Monat wird im Programm einfach mit einem Befehl aus einer Tabelle geholt.

Beispiel mit ccBasic:   Den heutigen Wochentag (DOW) bestimmen:

LOOKTAB Konstante,  month,  KM  ' Die Variable KM enthält nun den Wert aus der Tabelle

DOW = ((5 * year + KM) / 4  + day ) MOD 7 ' Tag 0 bis 6 (year 2-stellig für Jahr 2000 bis 2099)

Die Tabelle am Ende des Programms mit Namen Konstante lautet:

 TABLE Konstante 0 23 7 8 20 0 12 20 4 16 24 8 16 TABEND

Statt KM kann natürlich eine temporäre Variable z.B. wert3 benutzt werden.

Andere Methoden siehe Datum_berechnen allgemein

nach_oben

2.2.29)   Tag-Nummer im Jahr berechnen, Jahrestag  für Steuerungsgeräte in Basic z.B. c-control

(1)   Tagnummer bestimmen mit Programmzeilen (1901 bis 2099)

In diesem Programmteil wird der Jahrestag (Tag-Nr.) aus Day, Month und year  berechnet.

Dabei wird der 29.2. für Schaltjahre berücksichtigt.

define TagNr  word ' define wert12 word ,  define wert3 byte

TagNr = (month - 1) * 31 + day

 ' je nach Monat wird korrigiert

if month  >  2 then TagNr = TagNr –3

if month  >  2 AND year MOD 4 = 0 then  TagNr = TagNr + 1 ' Schaltjahr 29.2.

if month  >  4 then TagNr = TagNr – 1

if month  >  6 then TagNr = TagNr – 1

if month  >  9 then TagNr = TagNr – 1

if month  > 11 then TagNr = TagNr – 1

Nun liegt die Tag-Nummer 1 bis 365 (366) des aktuellen Jahres im word TagNr

Man kann auch die temporäre Variable wert12 anstelle TagNr anwenden um Variable zu sparen.

(2)   Tagnummer mit Formel errechnen für Programme z.B. Basic   (1901 bis 2099)

TagNr = Day + 30 *(Month –1) + Month * 9 / 16 + (Month >2)*(2 + (year MOD 4 = 0))

Erläuterungen: Der Klammerwert (Month >2) ist im Januar und Februar = 0 und ab März  = –1.

(year MOD 4 = 0) ist in Schaltjahren = –1  ansonsten = 0. Dadurch wird nach dem Februar mit –2  bzw. –1 korrigiert.

Bei einigen Programmiersprachen und Tabellenkalkulation bedeutet „wahr“ = +1, dann sind obige + durch – zu ersetzen.

year darf auch 2-stellig 00 bis 99 anstelle 1901 bis 2099 sein, weil eine Zahl durch 4 teilbar ist, wenn die letzten 2 Dezimalstellen durch 4 teilbar sind.

Kürzere Formel  zur Berechnung der Tagnummer

TagNr = Tag + 489 * Monat / 16 – 30 + (Month >2)*(2 + (year MOD 4 = 0))

Alternativer Weg  zur Berechnung der Tagnummer

TagNr = Tag + 489 * Monat / 16 – 30

if month  >  2  = 0 then  TagNr = TagNr – 2  ' Korrektur ab März wegen Februar

if month  >  2 AND year MOD 4 = 0 then  TagNr = TagNr + 1 ' Schaltjahr 29.2.

Tagnummer in Datum umformen   siehe Datum_berechnen allgemein

(3)   Zeiger für Datenspeicherung ( =Adresse)

Falls Daten z.B. Energieverbrauch je Tag nur für ein halbes Jahr gespeichert werden sollen:

Zeiger = TagNr MOD 184 ' 1 bis 183 und nochmals für 184 bis 366 ( 0 bis 182)

Für diesen Zeiger (kleiner 255) reicht auch ein Byte z.B. wert3 (temporäres Byte):

wert3 = TagNr MOD 184  ' 1 bis 183 und nochmals für 184 bis 366 ( 0 bis 182)

nach_oben

2.2.30)   Wochen-Nummer berechnen für Steuerungsgeräte in Basic z.B. c-control

Möchte man Betriebsstunden oder Energieverbrauch wöchentlich erfassen und je Woche speichern, dann benötigt man die Wochen-Nr.

Die Berechnung erfolgt mit der Tag-Nummer des Jahres, dessen Berechnung aus dem Datum siehe oben.

Das folgende Programm gibt die Kalenderwoche von Montag bis Sonntag aus.

Die europäische Norm wird eingehalten. Achtung, Woche 1 ist die Woche, in welcher der 4. Januar liegt.

Am Anfang und Ende des Jahres werden die richtigen Wochennummern bestimmt.

Zum Beispiel liegt der 31.12.2008  in Woche 1 des Jahres 2009.

2009 hat 53 Wochen und die ersten Tage 2010 liegen in Woche 53.

Eingänge des Programmbausteins sind Tag-Nr des Jahres in Variable wert12

 und year (zweistellig) 01 bis 99 für 2001 bis 2099 in Variable wert3  bzw. 4-stellig 1901 bis 2099

Ausgang (Ergebnis) ist die Wochen-Nr. in Variable wert3 mit zugehörigem Jahr in wert4.

Hier wurden temporäre Variablen verwendet, die in anderen Programmteilen wieder belegt werden können.

wert12 = TagNr  ' des Jahres 1 bis 365 bzw. 366

wert4 = year    ' Jahr zweistellig  bzw. 4-stellig je nach Unterprogramm

gosub WochenNr   ' Berechnung der Wochennummer

if wert3 = 0 then goto WoNull   ' à Woche vom 31.12. des Vorjahres

if wert3 = 53 then goto WoPruef  ' à Woche vom 1.1. des Folgejahres prüfen

goto ende  ' Fertig, Wochennummer liegt in Variable wert3

#WoPruef   '  Woche vom 1.1. des Folgejahres prüfen

wert12 = 1

wert4 = year +1

gosub WochenNr

if wert3 = 1 then goto ende ' à Fertig, Woche 1 des Folgejahres statt 53

wert3 = 53 '  Woche 53 ist richtig

wert4 = wert4  –1 ' Jahr rücksetzen

goto ende

#WoNull  ' gültig ist Woche vom 31.12. bzw. 30.12. des Vorjahres

wert12 =  365 ' Jahrestag 365 = 31. bzw. 30.12.

wert4 = year –1

gosub WochenNr   ' (Korrektur der Wochennummer)

goto ende  ' Fertig, Wochennummer 52 bzw. 53 liegt in Variable wert3

 ' Unterprogramm, Grundformel zur Bestimmung der Wochennummer 2000 bis 2099

#WochenNr ' Eingänge: year 2-stellig (wert3)  und Jahrestag (wert12)

' WoNr = ((( 5* year + 7) /4) Rest von Division durch 7 + TagNr +3) / 7 

wert3 = ((( 5 * wert4 + 7) / 4) MOD 7 + wert12 +3) / 7

return ' à Ausgang: Wochennummer (wert3)

#ende

print “ Woche: “;wert3; ;“ zu Jahr “;wert4;    ' Wochennummer mit zugehörigem Jahr

Wenn am Anfang des Jahres Woche 52 oder 53 gilt, dann zeigt das zugehörige Jahr wert4 das Vorjahr.

Wenn am Ende des Jahres Woche 1 gilt, dann ist das zugehörige Jahr wert4 das Folgejahr.

Bei 4-stelliger Jahreszahl (1901 bis 2099) gilt im Unterprogramm folgende Formel

WoNr =  ((( 5 * wert4 + 3) / 4) MOD 7 + wert12 +3) / 7

nach_oben

2.2.31)   Ostern (Tag und Monat) berechnen für Steuerungsgeräte in Basic oder Assembler

Die Berechnung der beweglichen Feiertage wird z.B. für das automatische Läuten der Kirchenglocken benötigt.

define Wert1 byte     '3 Zwischenspeicher 1 (zu wert12)

define Wert2 byte     '4 Zwischenspeicher 2 (zu wert12)

define Wert12 word [2] '= Byte 3,4 Zwischenspeicher

define Wert3 byte       ' Zwischenspeicher 3

(1)   Jahr (year) 2-stellig für 2000 bis 2099

wert3 = (204 (year + 5) MOD 19*11) MOD 30  '  (year 2-stellig für 2000 bis 2099)

wert3 = 120 + wert3 wert3 / 27 ' mit Ergänzung für Jahre 2049 und 2076

wert2 = (1+ wert3 + year * 5 / 4 ) MOD 7  

wert3 =  wert3 wert2 ' wert3 ist Bezug für alle anderen beweglichen Feiertage

wert1 = 1+ wert3 MOD 31    ' Ostersonntag (Datum Tag)

wert2 =      wert3 / 31             ' Ostermonat    (Monat)

print "Ostern ist am ";wert1;".";wert2;"  " 'Anzeige des Datums

if day = wert1 and month = wert2 then print “Frohe Ostern” 'Vergleich mit aktuellem Datum

(2)   Jahr (year) 4-stellig für 1900 bis 2099 bzw. 2199

wert3 = (204 Jahr MOD 19*11) MOD 30 ' Jahr 4-stellig

wert3 = 120 + wert3   wert3 / 27 '  mit Ergänzung für Jahre 2049 und 2076

wert2 = (wert3 + Jahr * 5 / 4) MOD 7 ' gültig  bis 2099 (Erweiterung bis 2199 siehe unten)

wert3 =  wert3 wert2  ' wert3 ist Osterkennzahl, Bezug für alle beweglichen Feiertage

wert1 = 1+ wert3 MOD 31    ' Ostersonntag (Datum Tag)

wert2 =      wert3 / 31             ' Ostermonat    (Monat)                                         

Erweiterung für Jahre 1900 bis 2199 anstelle obiger Zeile

wert2 = (wert3 + Jahr * 5 / 4 Jahr / 2100 ) MOD 7 ' mit Ergänzung gültig bis 2199

(3)   Jahr (year) 2-stellig für 2000 bis 2099  mit Tabellenzugriff

A = year MOD 19                          ' Zugriff auf Tabellenposition A = 0 bis 18 (year 2-stellig)

LookTAB  OstermondT­­2,  A, B     ' Die Variable B enthält nun den Wert Märztag (incl. April) +2 aus der Tabelle

C = (B + year + year /4) MOD 7     ' Wochentag Ostermond
E = B – C + 111                            ' E  Osterkennzahl (Easter index), Bezugswert für alle beweglichen Feiertage

K = B – C + 109                            ' K Karfreitagskennzahl. Nur für Karfreitag!

T = 1+ E MOD 31                 ' Ostersonntag  (Datum Tag)

M = E / 31                              ' Ostermonat     (Monat)

T = 1+ K MOD 31                 ' Karfreitag  (Datum Tag)

M = K / 31                             ' dazu der Monat

Beispiel einer Anwendung für Auswertung mit aktuellem Datum für Karfreitag

If  day = (1 + K MOD 31) AND  month = K / 31  then Musik nicht zulässig

 

TABLE  OstermondT2            ' Tabellenposition  0 bis 18
37  27  16  35  24  13  32  21  10  29  18  36  26  15  33  22  11  30  19

TABEND

(4)   Programm in Assembler für Microchip Controller PIC 16F628A

Siehe Assemblerprogramm_ Karfreitag

nach_oben

2.2.32)   Bewegliche Feiertage (Tag und Monat) berechnen

Rosenmontag, Aschermittwoch, Karfreitag, Ostermontag, Himmelfahrt, Pfingsten und Fronleichnam sind ebenfalls bewegliche Feiertage, denn sie sind an das Osterdatum gekoppelt. Die Unterprogramme gosub und Erläuterungen findet man weiter unten.

gosub Ostern   ' Datum Ostern (Osterkennzahl wert3) berechnen

wert12 = – 48  ' Rosenmontag liegt 48 Tage vor Ostersonntag

gosub Tage_zu_Ostern   ' Unterprogramm setzt Tag und Monat in wert1 und wert2

print "Rosenmontag ist am ";wert1;".";wert2;"  " 'Anzeige des Datums

if day = wert1 and month = wert2 then print “Helau”

Die anderen Feiertage können folgen ohne gosub Ostern, sofern die Osterkennzahl im byte wert3 nicht verändert wird.

In den temporären Speicher wert3 hat gosub Ostern die Osterkennzahl gesetzt, die von gosub Tage_zu_Ostern ausgewertet wird.

wert12 = 39 : gosub Tage_zu_Ostern    'Himmelfahrt liegt 39 Tage nach Ostern

if day = wert1 and month = wert2 then print “Vatertag”

nach_oben

2.2.33)   Buß- und Bettag mit Osterdatum bestimmen

Der Buß- und Bettag ist auch ein beweglicher Feiertag. Er bezieht sich zwar auf das feste Datum Weihnachten, aber er liegt immer auf einem Mittwoch (16. bis 22. November). Weil der 24.12. und der 30.4. immer auf dem gleichen Wochentag liegen, hatte ich die Idee, mit meiner Osterformel das Datum vom Buß- und Bettag zu berechnen.

Gosub Ostern  ' Datum Ostern (Osterkennzahl wert3) berechnen (z.B. Jahr 1900 bis 2199)

wert1 = 16 + wert3 MOD 7 ' Datum Tag für Buß- und Bettag

wert2 = 11                              'November

if day = wert1 and month = wert2 then print “heute ist Buß- und Bettag”

2.2.34)   Muttertag, Sommerzeit und Advent mit Osterdatum berechnen

Das Datum aller Tage, die Bezug zum Wochentag haben, können ebenfalls mit meiner obigen Osterformel bestimmt werden. Die Osterkennzahl stellt ja einen Bezug von Sonntag und Datum im jeweiligen Jahr her (gosub Ostern). Daraus wird mit MOD 7 (Rest nach Division = 0 bis 6) der Abstand in Wochentagen berechnet und zum frühest möglichen Datumstag addiert.

Der frühest mögliche Tag beim Muttertag ist der 8. Mai und bei der Sommerzeit der 25. März bzw. 25. Oktober.

Gosub Ostern  ' Datum Ostern (Osterkennzahl wert3) berechnen (z.B. Jahr 1900 bis 2199)

wert1 = 8 + wert3 MOD 7 ' Datum Tag für Muttertag, Sonderfall wegen Pfingsten siehe Datum_berechnen allgemein

Print “Muttertag ist am “;wert1;”. Mai “

wert1 = 18 + wert3 MOD 7 ' Datum Tag für 4. Advent im Dezember

wert1 = 11 + wert3 MOD 7 ' Datum Tag für 3. Advent im Dezember

wert1 =   4 + wert3 MOD 7 ' Datum Tag für 2. Advent im Dezember

wert1 = 1+ (26 + wert3 MOD 7 ) MOD 30 ' Datum Tag für 1. Advent im Dezember / November

wert2 = 12 – Tag / 27  ' Datum Monat  jeweils Tag des Advents (Dezember / November)

print “ 1. Advent ist am “;wert1;“.“;wert2;“.    

Bei der Sommerzeit sind zusätzlich Konstante notwendig, weil Monate nicht ein Vielfaches von Wochen sind.

Wert1 = 25+ (wert3 + 2 ) MOD 7 ' Datum Tag für Beginn Sommerzeit (Konstante = 2)

Wert2 = 25+ (wert3 + 5 ) MOD 7 ' Datum Tag für  Ende  Sommerzeit (Konstante = 5)

print “Sommerzeit ab “;wert1;“ März bis “;wert2;“ Oktober 

siehe auch Sommerzeit-Bit in  Teil 2 Uhr

nach_oben

2.2.35)   Steuern mit Feiertagsbit

Mit einem Feiertagsbit können Heizung und Rollladen z.B. später gestartet werden. Nach jedem gosub liegt außerdem das Datum des jeweiligen Feiertags als Tag (in wert1) und Monat (in wert2) und kann z.B. mit print ausgegeben werden.

'Deutsche Feiertage (unterschiedlich je nach Bundesland) und alle Sonntage (alternativ ohne Sonntage)

Andere Feiertage z.B. Bettag der Schweiz können wie der deutsche Buß- und Bettag mit der Osterkennzahl eingefügt werden.

Feiertagsbit = (DOW = 0) ' (Feiertagsbit = OFF ist die Alternative ohne Sonntage)

'Feste Feiertage vorgegeben im Format Monat Tag (mmdd)

wert12 = 101 : gosub Feiertag    'Neujahr 1.1.

wert12 = 501 : gosub Feiertag    '1. Mai

wert12 = 1003 : gosub Feiertag  'Tag der dt. Einheit

wert12 = 1225 : gosub Feiertag  '25. Dezember

wert12 = 1226 : gosub Feiertag  '26. Dezember

'An Ostern gekoppelte Feiertage (hilfsweise bei Buß- und Bettag)

gosub Ostern   'Datum Ostern (Osterkennzahl wert3) berechnen

gosub Buss_Bet_Tag  ' Buß- und Bettag Datum berechnen

wert12 = 48 : gosub Tage_zu_Ostern   'Rosenmontag (minus 48 Tage)

wert12 = 47 : gosub Tage_zu_Ostern   'Karnevaldienstag

wert12 = 46 : gosub Tage_zu_Ostern   'Aschermittwoch

wert12 = 2 : gosub Tage_zu_Ostern     'Karfreitag

wert12 = 1   : gosub Tage_zu_Ostern    'Ostermontag

wert12 = 39 : gosub Tage_zu_Ostern    'Himmelfahrt (39 Tage)

wert12 = 49 : gosub Tage_zu_Ostern    'Pfingstsonntag (49 Tage)

wert12 = 50 : gosub Tage_zu_Ostern    'Pfingstmontag (50 Tage)

wert12 = 60 : gosub Tage_zu_Ostern    'Fronleichnam (60 Tage)

 

Hier kann weiteres Hauptprogramm des Anwenders folgen.

goto Loop

2.2.36)   Unterprogramme feste und bewegliche Feiertage

'------- Unterprogramme----------------------------------------

#Feiertag        'mit  festem Datum  mmdd in Variabler wert12

wert3 = wert12 / 100  'Monat

wert1 = wert12 MOD 100 'Tag

wert2 = wert3                   'Monat

' Return ' falls ohne Vergleich z.B. Ausgabe des Datums mit print

goto Feiertagsdatum ' Vergleich mit heute

#Ostern 'Ostersonntag  (year 2-stellig für 2000 bis 2099)

wert3 = (204 (year + 5) MOD 19*11) MOD 30

wert3 = 120 + wert3 - wert3 / 27 ' mit Ergänzung für Jahre 2049 und 2076

wert2 = (1+ wert3 + year * 5 / 4 ) MOD 7  

wert3 =  wert3 wert2 ' Osterkennzahl wert3 ist Bezug für alle anderen beweglichen Feiertage

wert1 = 1+ wert3 MOD 31    'Ostersonntag

wert2 = wert3 / 31                 'Ostermonat

' Return ' falls ohne Vergleich z.B. Ausgabe des Datums mit print

goto Feiertagsdatum ' Vergleich mit heute

#Tage_zu_Ostern  'an Ostern (wert3) gekoppelte Feiertage

' Erläuterungen:

'+ wert2 / 154  ist Korrektur für fehlenden 31.4. für Feiertage nach 1. Mai.

'+(wert2 < 93)*(3+ (year MOD 4=0 ) (Jahr =2100)) ist Korrektur für Karnevalstage im Februar (-2 bzw. –3Tage).

Dabei darf year 2-stellig oder 4-stellig sein. (Jahr =2100 wird bei 2-stellig weg gelassen.

' Der Klammerwert (wert2  < 93) ist im Januar und Februar = –1 und ab März  = 0.

 ' (year MOD 4 = 0) ist in Schaltjahren = –1  ansonsten = 0.

 ' (Jahr =2100) ist im genannten Jahr =  –1  ansonsten = 0.

wert2 = wert3 + wert12          'Ostersamstag + Abstand Feiertag (wert12)

wert2 = wert2 + wert2 / 154 + (wert2 < 93)*(3+ (year MOD 4 = 0) (Jahr =2100)) 'mit Ergänzung Karnevalstage

wert1 = 1+ wert2 MOD 31     ' Datum Tag

wert2 = wert2 / 31                   ' Datum Monat

' Return ' falls ohne Vergleich z.B. Ausgabe des Datums mit print

goto Feiertagsdatum ' Vergleich mit heute

#Buss_Bet_Tag 'Eingang: wert3 von gosub Ostern

wert1 = 16 + wert3 MOD 7   ' Datum Tag für Buß- und Bettag

wert2 = 11                              ' November

' Return ' falls ohne Vergleich z.B. Ausgabe des Datums mit print

#Feiertagsdatum ' Vergleich mit heute

if day = wert1 and month = wert2 then Feiertagsbit = ON

Return

 

weitere Berechnungen zum Datum bei  Datum_berechnen allgemein

------------------------------------------------  ENDE   Tipps und Tricks  Teil  2 ------------  nach_oben

 --------------------- weiter zu  Teil 3   Teil 4    zurück zu Tipps und Tricks Teil_1                        Startseite

Kostenlose Zähler und Statistiken für Ihre Website bei www.motigo.com