ein Kapitel zurück                                           ein Kapitel weiter

Manches mal benötigt bestimmte Kalenderdarstellungen wo man mit der Headerdatei <time.h> nicht mehr erreicht. Dazu gibt es die sogenannten Kalenderalgorithmen. Was machen sie z.B. wenn sie wissen wollen welcher Tag am 10.10.1520 war? Zum Glück gibt es immer ein paar Mathematische Genies die dafür Algorithmen geschrieben haben. Wir wollen nun den Tag herausfinden mit dem...

Algorithmus von Zeller

/*Download:zeller.c*/
#include <stdio.h> char *wochentag[] = {"Samstag", "Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag" , "Freitag" }; /*Berrechnung des Wochentages nach gregorianischem Kalender c=Nummer des Jahrhunderts; y=Nummer des Jahres im laufenden Jahrhundert; wt=Wochentag */ void zeller(int tag, int monat, int jahr) { int c,y,wt; if(monat<3) { monat+=12; jahr-=1; } y=jahr % 100; c=jahr / 100; wt=(tag+(monat+1)*13/5+y+y/4+c/4-2*c) % 7; if(wt<0) wt+=7; printf("war ein %s\n",wochentag[wt]); } int main() { int tag,monat,jahr; printf("Eingabe (Tag): "); scanf("%d",&tag); printf("Eingabe (Monat) : "); scanf("%d",&monat); printf("Eingabe (Jahr) : "); scanf("%d",&jahr); printf("%2d.%2d.%4d ",tag,monat,jahr); zeller(tag,monat,jahr); return 0; }

Natürlich stellt dieser Algorithmus nicht das Nonplusultra dar. Es gibt natürlich noch andere Algorithmen womit sich der Wochentag irgendeines Datums berechnen lässt. Dies gilt auch für die weiteren Programme in diesem Kapitel. Ich finde aber ein Beispiel pro Thema reicht.

Kommen wir nun von dem gregorianischem Kalender zum Julianischen der vorwiegend in der Astronomie und Raumfahrt Verwendung findet. Dieser Tag beginnt mit seiner Berechnung ab dem Beginn der ägyptischen Berechnung seit dem 1.1.4713 v. Christus Mit dem Julianischen Datum lässt sich auch sehr gut die Sonnen - bzw. Mondfinsternis berechnen......

/*Download:julian.c*/
#include <stdio.h> /*Berechnung mit dem Julianischem Datum*/ void julian(int tag, int monat, int jahr) { int k,l,jd; k=(monat-14)/12; l=jahr+k+4800; jd=tag-32075+1461*l/4 + 367* ((monat-2-12*k)/12)-3*((l+100)/100)/4; printf("sind %d Tage vergangen\n",jd); } int main() { int tag,monat,jahr; printf("Eingabe (Tag): "); scanf("%d",&tag); printf("Eingabe (Monat) : "); scanf("%d",&monat); printf("Eingabe (Jahr) : "); scanf("%d",&jahr); printf("Seit dem 1.1.4713 v.Chr. bis %2d.%2d.%4d ",tag,monat,jahr); julian(tag,monat,jahr); return 0; }

Nun gut werden sie sich sagen, was bringt es mir jetzt wenn ich weis wie viele Tage seit dem 1.1.4713 v.Chr. vergangen sind? Außer den oben genannten Beispielen der Anwendung lassen sich damit prima die Differenzen zwischen 2 Daten und Wochentage bestimmen. Aber dazu benötigen wir erst wieder einen Algorithmus mit dem wir das Julianische Datum wieder in das Gregorianischen Umwandeln. Oder wissen sie auf Anhieb welches Datum und welcher Wochentag wir in 123 Tagen haben? Hier nun unser Programm dazu........

/*Download:jul2greg.c*/
#include <stdio.h> #include <time.h> /*Prototypen*/ void zeller(long , long , long); long julian(int , int, int); void jul2greg(long ); char *wochentag[] = { "Samstag", "Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag" , "Freitag" }; /*Berechnung mit dem Julianischem Datum*/ long julian(int tag, int monat, int jahr) { long k,l,jd; k=(monat-14)/12; l=jahr+k+4800; jd=(long)(tag-32075+1461*l/4 + 367* ((monat-2-12*k)/12)-3*((l+100)/100)/4); return jd; } /*Julianisches Datum Umkehren zu Gregorianischem Datum*/ void jul2greg(long jultage) { long greg=2299161,a,alpha,b,c,d,e,t,tc,m,mc,j; jultage=jultage+1; if(jultage<greg) a=jultage; else { alpha=(jultage-1867216.25)/36524.25; a=jultage+1+alpha-(alpha/4); } b=a+1524; c=(b-122.1)/365.25; d=1461*c/4; e=(b-d)/30.6001; t=(b-d) - (long)(30.6001*e)-1; if(t==0) tc=31; else tc=t; if(e<13.5) m=e-1; else m=e-13; if(m>2.5) j=c-2814; else j=c-2813; if(tc==31) mc=m-1; else mc=m; printf("Das von Ihnen gewuenschte Datum ist %2ld.%2ld.%4ld an einem ",tc,mc,j); zeller(t,m,j); } void zeller(long tag, long monat, long jahr) { long c,y,wt; tag-=1; if(monat<3) { monat+=12; jahr-=1; } y=jahr % 100; c=jahr / 100; wt=(tag+(monat+1)*13/5+y+y/4+c/4-2*c) % 7; if(wt<0) wt+=7; printf("%s\n",wochentag[wt]); } int main() { long tage,diff; time_t sekunden; struct tm *heute; time(&sekunden); heute=localtime(&sekunden); printf("Wieviele Tage benoetigen sie fuer den Auftrag : "); scanf("%ld",&tage); diff=julian(heute->tm_mday,heute->tm_mon,heute->tm_year)+tage; jul2greg(diff); return 0; }

Kommen wir zu einem weiteren Algorithmus von Robertson womit wir die Nummer eines Tages im Jahr berechnen können. Unser Programm gibt einfach den heutigen Jahrestag (0-365) aus....

/*Download:robert~1.c*/
#include <stdio.h> #include <time.h> void daynumber(int tag, int monat, int jahr) { int a,b,c,d,e,number; a=jahr%4; b=jahr%100; c=jahr%400; d=(monat+10)/13; e=tag+3055*(monat+2)/100-2*d-91; number=e+(1-(a+3)/4+(b+99)/100-(c+399)/4)*d; printf("Heute ist der %d -te Tag im Jahr!\n",number); } int main() { long tage,diff; time_t sekunden; struct tm *heute; time(&sekunden); heute=localtime(&sekunden); daynumber(heute->tm_mday,heute->tm_mon+1,heute->tm_year); return 0; }

Nun will ich langsam mit diesem Thema belassen. Es gibt zwar noch mehr Algorithmen zu diesem Thema, aber die wichtigsten die man sicherlich mal benötigt waren mir wichtiger als Quantität. Ein Tipp vielleicht falls sie noch weitere Kalenderberechnungen benötigen : Kaufen sie sich in der Bücherei ein Buch mit Formelsammlungen der Mathematik aller Art. Diese Formeln brauchen sie anschließend in Ihrem Programm nur ein bisschen anpassen und die Zahlen die zur Berechnung benötigen einsetzen. Speziell wenn sie später im Kurs zur Grafikprogrammierung kommen tun sie sich mit einem solchem Buch leichter.

Vielleicht eine Funktion will ich noch zur Ergänzung hinzufügen. Die Berechnung ob ein Jahr ein Schaltjahr ist (wegen der Monatstage im Februar der falls Schaltjahr 29 Tage ansonsten 28 Tage beträgt).....

/*Download:schalt.c*/
#include <stdio.h> /*Ein Schaltjahr ist dann ein Schaltjahr wenn sich die Jahreszahl dividieren lässt durch 100 mit Rest und 4 ohne Rest oder wenn sich die Jahreszahl dividieren lässt durch 400 ohne das ein Rest dabei herauskommt*/ int istSchaltjahr( int jahr) { return (((jahr%4==0) && (jahr%100!=0))?1:(jahr%400==0)?1:0); } int main() { int jahr; printf("Bitte die Jahreszahl eingeben (jjjj) : "); scanf("%d",&jahr); if(istSchaltjahr(jahr)) printf("Jahreszahl ist ein Schaltjahr!\n"); else printf("Jahreszahl ist kein Schaltjahr!\n"); return 0; }

ein Kapitel zurück          nach oben           ein Kapitel weiter


© 2001,2002 Jürgen Wolf