// // Datei: // Autor: // // Erzeugt am 08. Juni 2007, 13:36 // #include // Header für Ausgabe an die Konsole #include // Datumspezifischer Header #include // Funktionen für Strings #include // Brauch ich für funktion atoi() #include // Brauch ich zum Runden /* * Klassenname: workdays * Beschreibung: berechnet Arbeitstage */ class workdays { public: workdays(); //Konstruktor int getWorkdays(); //liefert arbeitstage, wenn es -1 liefert dann ist das Enddatum vor dem Anfangsdatum void saturdayfree(bool free); //Stellt ein ob samstag als frei oder nicht zählt bool saturdayfree(); //Fragt ab ob Samstag frei oder nicht bool setStartday(int tag, int monat); //Setzt Starttag, Liefert false wenn nicht setzbar bool setFinalday(int tag, int monat); //Setzt Endtag, Liefert false wenn nicht setzbar int getSundays(); //Liefert freie Sonntage int getSaturdays(); //Liefert freie Samstage int getHolidays(); //Liefert freie Feiertage int getTotalDays(); //Liefert die Anzahl der Tage in dem Zeitraum int getAdjustment(); //Liefert Feiertagsanpassung private: //Funktionen bool checkdate(int tag, int monat); //Checkt ob Datum korrekt ist. struct tm maketime(int tag, int monat); //Verwandelt Datum in ein tm int holidaycounter(int zeitraum1, int zeitraum2); //Liefert die Anzahl der Feiertage //Variablen struct tm startday; //Starttag struct tm finalday; //Endtag bool saturday; //Samstag arbeitstag? int monatlen[13]; //Tage im Monat int holidayarr[12]; //Alle Feiertage int freeSundays; //freie Sonntage int freeSaturdays; //freie Samstage int freeHolidays; //freie Feiertage int totalDays; //Zeitraum in Tagen int freeAdjustment; //Anpassung wenn Feiertag auf Wochenende fällt }; workdays::workdays() { //variablen initialisieren saturday=false; freeSundays=0; freeSaturdays=0; freeHolidays=0; freeAdjustment=0; //Tage im Monat bezogen auf 2008 und da hat Februar 29 Tage monatlen[1] = 31; monatlen[2] = 29; monatlen[3] = 31; monatlen[4] = 30; monatlen[5] = 31; monatlen[6] = 30; monatlen[7] = 31; monatlen[8] = 31; monatlen[9] = 30; monatlen[10] = 31; monatlen[11] = 30; monatlen[12] = 31; //gesetzliche Feiertage 2008 Quelle: www.austria.info //Format ist mmdd wenn monat nur 1 lang ist dann mdd holidayarr[0] = 101; // 01. Jänner: Neujahrstag (Dienstag) holidayarr[1] = 106; // 06. Jänner: Heilige Drei Könige (Sonntag) holidayarr[2] = 324; // 24. März: Ostermontag (Montag) holidayarr[3] = 501; // 01. Mai: Staatsfeiertag und Christi Himmerlfahrt (Donnerstag) holidayarr[4] = 512; // 12. Mai: Pfingstmontag (Montag) holidayarr[5] = 522; // 22. Mai: Fronleichnam (Donnerstag) holidayarr[6] = 815; // 15. August: Mariä Himmelfahrt (Freitag) holidayarr[7] = 1026; // 26. Oktober: Nationalfeiertag (Sonntag) holidayarr[8] = 1101; // 01. November: Allerheiligen (Samstag) holidayarr[9] = 1208; // 08. Dezember: Mariä Empfängnis (Montag) holidayarr[10] = 1225; // 25. Dezember: Christtag (Donnerstag) holidayarr[11] = 1226; // 26. Dezember: Stephanitag (Freitag) } int workdays::getWorkdays(){ double dts=0; //Zeitunterschied in Sekunden int dtt=0; //Zeitunterschied in Tagen int arbeitstage=0; //Absolute Arbeitstage int freitemp=0; //Tagepuffer dts = difftime(mktime(&finalday),mktime(&startday)); //Zeitunterschied ausrechnen und durch mktime wird der wochentag ergänzt. dts = dts+(60*60*24); //Ich rechne einen ganzen Tag dazu, weil ich inklusive Start und Endtag rechne dtt = (int)((double)dts/(double)(60*60*24)); //Zeitunterschied in Tagen ausrechnen (lieber auf Nr. sicher mit typecast) totalDays = dtt; //Übertragung der Tage if(dts < 0) { //Enddatum befindet sich vor dem Anfangsdatum return -1; } else if(dts == 0){ //Enddatum und Anfangsdatum sind gleich (oder nie eingegeben worden) return 0; } else { //Datum soweit korrekt: Freie Samstage und Sonntage zählen if(startday.tm_wday == 0) { freeSundays++; //Schon ein freier Sonntag } if(dtt < (6-startday.tm_wday)+1) { //Weniger Zeit als bis zum nächsten Samstag arbeitstage = dtt-freeSundays; } else { dtt= dtt-(6-startday.tm_wday)-1; //Zeit bis Samstagwird abgezogen arbeitstage = (6-startday.tm_wday)+1; //Und als arbeitstage gewertet freeSaturdays++; //Weil wir den ersten freien Samstag erreicht haben. freitemp = (int)(floor(dtt/7)); //Weil alle 7 Tage kommt ein Sa dazu freeSaturdays = freeSaturdays+freitemp; //So viele Samstage sind zusätzlich frei freeSundays = freeSundays+freitemp; //Weil es werden gleich viele So wie Sa auf jeden Fall erwischt if(dtt%7!=0) { //Endet genau auf Samstag freeSundays++; //Ein Sonntag wird mehr erwischt als Samstage } arbeitstage = arbeitstage+dtt-freeSundays; //Sonntage werden abgezogen if(saturday) { //Falls samstag als frei zählt: arbeitstage=arbeitstage-freeSaturdays; //Samstage werden abgezogen } } //Berechnet die in den Zeitraum fallenden Feiertage freeHolidays = holidaycounter(((startday.tm_mon+1)*100+startday.tm_mday),((finalday.tm_mon+1)*100+finalday.tm_mday)); arbeitstage = arbeitstage - freeHolidays + freeAdjustment; //Feiertage von arbeitstagen abziehen } return arbeitstage; } int workdays::holidaycounter(int zeitraum1, int zeitraum2) { int i=0; //Laufvariable int counter=0; //Zählvariable for(i=0;i<=11;i++) { //Da es ein Array mit 11 Elementen ist if((zeitraum1 <= holidayarr[i]) && (holidayarr[i] <= zeitraum2)) { counter++; //Ein feiertag kommt vor if((i==1) || (i==7)) { //Weil die auf Sonntag fallen freeAdjustment++; } if((saturday) && (i==8)) { //Weil der auf Samstag fällt freeAdjustment++; } } } return counter; } void workdays::saturdayfree(bool free) { saturday = free; } bool workdays::saturdayfree() { return saturday; } bool workdays::setStartday(int tag, int monat) { if(checkdate(tag,monat)) { startday = maketime(tag,monat); return true; } else { return false; } } bool workdays::setFinalday(int tag, int monat){ if(checkdate(tag,monat)) { finalday = maketime(tag,monat); return true; } else { return false; } } bool workdays::checkdate(int tag, int monat) { bool ret = true; if((monat > 12) || (monat < 1)) { //Monatseingabe kontrollieren ret = false; } else if((tag > monatlen[monat]) || (tag < 1)) { //Tageseingabe kontrollieren, bezogen auf Monat ret = false; } return ret; } struct tm workdays::maketime(int tag, int monat) { struct tm time_check; //Structure für spätere Umwandlung in t_time time_check.tm_year = (2008-1990); //Weil ja von 2008 ausgegangen wird und year ab 1990 zu zählen beginnt time_check.tm_mon = (monat-1); //Monat beginnt bei 0 time_check.tm_mday = tag; //---Uhrzeit wird auf 00:00:01 gesetzt---// time_check.tm_hour = 0; time_check.tm_min = 0; time_check.tm_sec = 1; time_check.tm_isdst = -1; return time_check; } int workdays::getSundays(){ return freeSundays; } int workdays::getSaturdays() { return freeSaturdays; } int workdays::getHolidays() { return freeHolidays; } int workdays::getTotalDays() { return totalDays; } int workdays::getAdjustment() { return freeAdjustment; } /* * Ende der Klasse workdays */ // // Main Funktion: // int main(int argc, char** argv) { char eingabe[100]; //Wahllos 100 genommen. Damit sich ja für alle eingaben alles ausgeht. Ist nur ein Eingabepuffer. char *pZerlege; //Pointer der mir zerlegt. int datum[]={0,0}; //Datumspeicher int i=0; //Laufvariable 1 int j=0; //Laufvariable 2 int anzwork=0; //Anzahl der Arbeitstage workdays work; //Instanz der Klasse workdays erzeugen. cout << "Berechnen der Arbeitstage (Jahr 2008):\nEinstellungen: "; //---Samstag arbeit?---// cout << "Soll der Samstag als arbeitsfreier Tag zählen? "; fgets(eingabe,6,stdin); //Einlesen der Eingabe! Immer daran denken, dass ein \n und ein \0 noch drangehängt werden! eingabe[strlen(eingabe)-1] = '\0'; //Das \n am schluss überschreiben if(strncmp(eingabe,"ja",strlen(eingabe)) == 0) { //Nur j geht auch work.saturdayfree(true); //Setzt Samstag als Arbeitstag } else if(strncmp(eingabe,"nein",strlen(eingabe)) == 0) { //Nur n geht auch work.saturdayfree(false); //Setzt Samstag als arbeitsfreier Tag } else { cout << "Falsche Eingabe! Groß und Kleinschreibung beachtet? Programm wird beendet\n"; return (EXIT_SUCCESS); } //---Datum Eingabe---// for(j=1;j<=2;j++) { if(j==1) { cout << "Bitte geben Sie das Startdatum ein: "; } else { cout << "Bitte geben Sie das Enddatum ein: "; } fgets(eingabe,7,stdin); //Einlesen des Datums eingabe[strlen(eingabe)-1] = '\0'; //Das \n am schluss überschreiben pZerlege = strtok(eingabe,"."); //Sucht bis "." in dem String i = 0; while(pZerlege != NULL){ if(i==2) { cout << "Datumeingabefehler!!! Zu viele Punkte Programm wird beendet\n"; return (EXIT_SUCCESS); } datum[i] = atoi(pZerlege); //Schreibt ersten Teil in Array pZerlege = strtok(NULL,"."); //Nächster Teil i++; //Erhöht Laufvariable } if(j==1) { if(!work.setStartday(datum[0],datum[1])) { //Übergibt Datum und liefert obs funktioniert hat cout << "Konnte Startdatum nicht setzen: Ungültiges Datum\n"; j--; //Damit noch einmal nach Startdatum gefragt wird } } else { if(!work.setFinalday(datum[0],datum[1])){ //Übergibt Datum und liefert obs funktioniert hat cout << "Konnte Enddatum nicht setzen: Ungültiges Datum\n"; j--; //Damit noch einmal nach Startdatum gefragt wird } } } //---Ausgabe der Tage---// anzwork = work.getWorkdays(); //Führt Rechendurchgang durch und liefert auch gleich die Anzahl der Tage if(anzwork == -1) { cout << "Enddatum ist vor dem Anfangsdatum. Es fand keine Berechnung statt.\n"; } else { //Ausgabe schön: cout << "\nDie Anzahl der Arbeitstage beträgt " << anzwork << " Stück\n\n"; cout << "Von den " << work.getTotalDays() << " Tagen die sich in diesem Zeitraum befinden sind " << work.getSaturdays() << " Samstage, " << work.getSundays() << " Sonntage und " << work.getHolidays() << " Feiertage vorhanden. Von den Feiertagen fallen " << work.getAdjustment() << " auf ein Wochenende. Nach Abzug der freien Tage kommt man somit auf " << anzwork << " Arbeitstage.\n\n"; /* //Ausgabe Nutzen cout << "\n\n|" << work.saturdayfree() << "|" << anzwork << "|" << work.getSundays() << "|" << work.getSaturdays() << "|" << work.getHolidays() << "|" << work.getAdjustment() << "|" << work.getTotalDays() << "|"; */ } return (EXIT_SUCCESS); }