/** DATE.C ********************************************************** Datumsfunktionen MAKROS DAYSMAX definiert die Anzahl der gültigen Tage seit 1970 SCHALTJAHR wenn wahr __C51__ auch mit BORLANDC kompilierbar LOCAL i_datum zählt die Tage beginnend bei 1.1.1970 PUBLIC date_set_inc() Datum im 1 erhöhen (nächster Tag) date_set_d() Datum als Anzahl von Tagen seit 1.1.70 einstellen date_get_d() Datum als Anzahl von Tagen seit 1.1.70 ablesen Gregorianischer Kalender Regel 1: alle 4 Jahre ist ein Schaltjahr ...1980,1984,1988,1992,1996,2000... Regel 2: alle 100 Jahre ist kein Schaltjahr ...1700,1800,1900,2000... Regel 3: alle 400 Jahre ist doch ein Schaltjahr ...1600,2000... date() Überprüft ein Datum auf Richtigkeit date_set_jmt date_get_jmt(unsigned char *jahr, unsigned char *monat, unsigned char *tag) wochentag() Berechnet den Wochentag für ein beliebiges Datum heute() Berechnet den Wochentag wochentag_s() Berechnet den Wochentag für ein beliebiges Datum als Zeichenfolge heute_s() Berechnet den Wochentag als Zeichenfolge *******************************************************************/ #ifdef LDEBUG #define hide #else #define hide static #endif #ifndef __C51__ #define xdata #endif #define DAYSMAX (50*365U) /* Kalender bis 2020 verwendbar */ #define SCHALTJAHR(x) ( (((x)%4==0) && ((x)%100)) || ((x)%400==0) ) /** LOCAL **********************************************************/ /* i_datum zählt die Tage beginnend bei 1.1.1970 */ hide unsigned int xdata i_datum = 0; hide unsigned char *wtag[] = {"So","Mo","Di","Mi","Do","Fr","Sa"}; /** PUBLIC **********************************************************/ void date_set_inc(void) { i_datum++; } void date_set_d(unsigned int days) { i_datum = (days%DAYSMAX); } unsigned int date_get_d(void) { return i_datum; } /* date() *********************************************** überprüft ein Datum auf seine Richtigkeit ***********************************************************/ unsigned char date(unsigned char jahr, unsigned char monat, unsigned char tag) { unsigned int xdata jahrh; /* grobe Überprüfung */ if ( (monat>12) || ((jahr<70)&&(jahr>20)) || (tag>31) ) return 0; if (jahr<70) jahrh = 2000 + jahr; else jahrh = 1900 + jahr; /* alle von vornherein gültigen Tage zulassen */ if (tag<=28) return 1; /* kritische Monate prüfen */ switch (monat) { /* Monate mit 30 Tagen */ case 4: case 6: case 9: case 11: if (tag==31) return 0; break; case 2: switch (tag) { case 31: case 30: return 0; case 29: /* Schaltjahr */ if SCHALTJAHR(jahrh) return 0; break; } break; default: /* alles OK */ break; } return 1; } unsigned char date_set_jmt(unsigned char jahr, unsigned char monat, unsigned char tag) { unsigned int xdata jahrh; /* Jahr inklusive Jahrhunderte */ unsigned int xdata j; /* Jahreszähler */ if (!date(jahr,monat,tag)) return 0; if (jahr<70) jahrh = 2000 + jahr; else jahrh = 1900 + jahr; /* Zählung der vollen Jahre seit 1970 */ i_datum = 0; for (j=1970; jjahrtage) { datum -= jahrtage; jahranzahl++; } else break; j++; } if (j>=2000) *jahr = j-2000; else *jahr = j-1900; m=1; for (;;) { switch (m) { /* in jedem Monat wird die Dauer des Vormonats addiert */ case 12: case 10: case 8: case 7: case 5: case 3: case 1: monattage = 31; break; case 11: case 9: case 6: case 4: monattage = 30; break; case 2: monattage = 28; if SCHALTJAHR(j) monattage++; break; } if (datum>monattage) { datum -= monattage; m++; } else break; } *monat = m; *tag = datum; } /* wochentag *************************************** Berechnet den Wochentag für ein beliebiges Datum gegeben durch tag, mon, jahr ohne Fehlerprüfung, d.h. Datum muss korrekt sein z.B. 72.11.1999 ist nicht erlaubt */ /* AD 0 war ein Sonntag tag=0 */ /* 31.12 des Vorjahres jahr-1 */ /* der Neujahrstag ist normalerweise einen Tag nach dem Neujahrstag des Vorjahres */ /* jahr-1 %7 wäre der Wochentag ohne Schaltjahre */ unsigned char wochentag(unsigned char jahr, unsigned char monat, unsigned char tag) { int xdata iWochentag; unsigned int xdata jahrh = jahr+1900; if (jahr<20) jahrh+=100; iWochentag=(jahrh-1 + (jahrh-1)/4 - (jahrh-1)/100 + (jahrh-1)/400) %7; /* Wochentage des laufenden Jahres */ iWochentag+=(monat-1)*31-(monat-1)/2; /* Monate mit 30 Tagen wegen Augustus */ if (monat==9 || monat==11) iWochentag++; /* Berücksichtigung des Februars */ if (monat>=3) iWochentag-=2; /* Berücksichtigung des Schaltjahres */ if ( SCHALTJAHR(jahr) && (monat>=3) ) iWochentag++; /* Wochentage des laufenden Monats */ iWochentag+=tag; iWochentag%=7; return iWochentag; } unsigned char *wochentag_s(unsigned char jahr, unsigned char monat, unsigned char tag) { return wtag[wochentag(jahr,monat,tag)]; } unsigned char heute(void) { unsigned char dj,dm,dt; date_get_jmt(&dj,&dm,&dt); return wochentag(dj,dm,dt); } unsigned char *heute_s(void) { return wtag[heute()]; }