Laden...

Suche Denkansätze für die Berechnung von Zeiten

Erstellt von Doltsche vor 14 Jahren Letzter Beitrag vor 12 Jahren 6.638 Views
D
Doltsche Themenstarter:in
249 Beiträge seit 2009
vor 14 Jahren
Suche Denkansätze für die Berechnung von Zeiten

Hallo zusammen

Ich stehe derzeit vor einem für mich recht schweren Problem.
Ich schreibe im Rahmen meiner Ausbildung ein Programm, mit dessen Hilfe sich der Lohn ausrechnen lässt. Dazu gibt man in einer Tabelle die Zeit des Arbeitsbeginns und die Zeit des Arbeitsende ein. Gegebenfalls kann man die Anzahl der Nachtdienste angeben:

Siehe Anhang

Das klingt alles ersteinmal ganz einfach. Nun kommt aber die schwierigkeit: Der Lohn pro Stunde ist nicht konstant. Ich habe hier eine Tabelle, wie sich der Lohn berechnet:

Siehe zweiten Beitrag (Anhang)

Leider stosse ich bei dieser Aufgabe an meine Grenzen und habe keine Ahnung wie ich vorgehen soll . Nun möchte ich euch um mögliche Denkansätze bitten wie ich da vorgehen soll, welche überlegungen ich anstellen soll etc.
Eine komplette Lösung möchte ich allerdings nicht, ich will ja selbst auch etwas dazu beitragen und vorallem etwas lernen.
Klar ist sicherlich, dass man die Zeiten mit einer Schleife durchlaufen muss.
Im übrigen können die Zeiten auch in Minuten angegeben werden, also nicht nur in Stunden wodurch es wieder etwas schwerer wird.

Ausserdem würde mich noch interessieren, welchem Schwierigkeitsgrad diese Aufgabe unterliegt. Mit fast 19 Jahren komme ich mir etwas dumm vor, dass ich bei dieser Aufgabe bereits an meine Grenzen stosse...

Hoffe Ihr könnt mir bald nützliche Tipps geben und vielen Dank schonmal

Liebe Grüsse

Samuel

D
Doltsche Themenstarter:in
249 Beiträge seit 2009
vor 14 Jahren

Berechnung des Lohns

Gelöschter Account
vor 14 Jahren

ja so eine aufgabe ist schon ein wenig anstrengender aber nicht unlösbar.

du hast generell 3 zeitslots. du musst zuerst berechnen wieviele minuten der arbeitszeit in welchem zeitslot liegen. das kannst du recht einfach mit dem DateTime oder TimeSpan klassen herausfinden.

hast du die timeslots mit den gesamtminuten berechnet, musst du die multiplikatoren festlegen. diese sind je nach wochentag anders (hier wäre es wichtig zu wissen, wie der nachts-zeitslot von freitag auf samstag gehandhabt wird?).

du musst dann die anzahl der minuten in stunden umrechnen. das ergibt eine gleitkommazahl, die du unbedingt in einem Decimal-struct festhalten musst, da double und float gerde für die finanzmathematik nicht ausreichend genau sind. (siehe [FAQ] Double und Float: Fehler beim Vergleich und Rundungsfehler )

zusätzlich in die multiplikatorenberechnung solltest du die anzahl der nachtdieste einfließen lassen (ab 2 mal im monat ist ja ein anderer multiplikator gefragt).

wenn du die multiplikatoren und die stunden (gesamtminuten/60) berechnet hast nimmst du nur noch die stunden * passender multiplikator und zählst alle drei timeslots zusammen.

fertig 😃

D
Doltsche Themenstarter:in
249 Beiträge seit 2009
vor 14 Jahren

Hallo

Danke für die Antwort.
Leider liegt mein Problem nicht zuletzt darin, die Zeit in die Zeitslots zu verteilen.
Ich habe da mal etwas probiert; eine Funktion, die bestimmen sollte, wie viele Minuten der angegebenen Zeit im Zeitslot 7:00 bis 20:00 Uhr liegen.
In der Datenbank habe ich die Zeiten 23.11.2009 08:00:00 bis 23.11.2009 09:05:00 hinterlegt. Dass das mit der If Abfrage nicht funktioniert, wenn die Arbeitszeit den Zeitslot überlappt ist mir klar. Da muss ich noch was ändern.
Nicht klar ist mir allerdings, weshalb das Programm abschmiert, wenn ich die Funktion ausführe. Fehlermeldung kommt keine. Es heisst lediglich im Fenstertitel "keine Rückmeldung".

Mein Versuch sieht folgendermassen aus:

 class TimeDivide
    {
        public int TpS = 0;
        //TimeSpan 
        public int divide(DateTime beginn, DateTime ende)
        {
            while (beginn < ende)
            {
                if(beginn.Hour + beginn.Minute >= 7 && beginn.Hour + beginn.Minute <= 20)
                {
                    TpS += 1;
                    beginn.AddMinutes(1);
                }
                else
                    beginn.AddMinutes(1);
            }
            return TpS;
        }
    }

Ich hoffe ihr könnt mir weiterhelfen und danke bereits vielmals.

Liebe Grüsse

Samuel

Gelöschter Account
vor 14 Jahren

abstürzen ist die flasche annahme. not responding bedeutet, das er noch bei der ausführung ist (endlosschleife oder viel zu lang andauernde aktion) und das er während dieser ausführung keine windowsnachrichten bearbeiten kann. dann kommt das "not responding". hier zu ist das da interessant: [FAQ] Warum blockiert mein GUI?

deine methode verfolgt den bruteforce ansatz. das ist so ziemlich das unperfomanteste.

mach das am besten so das du die startzeit des timeslots von der arbeitszeit abziehst.
also 08:00 uhr - 07:00 uhr

wenn das ein positives ergebniss liefert, das jedoch kleiner 07:00 uhr - 20:00 uhr ist, dann ist der startzeitpunkt in diesem zeitslot.

dann berechnest du die gesamtzeit der arbeitszeit:
08:00 uhr - 09:05 uhr

ist das ergebniss kleiner als 07:00 uhr - 20:00 uhr, dann musst du andere zeitslots garnichtmehr betrachten und du hast gleichzeitig auch die gesamtarbeitszeit dieses zeitslots.

D
Doltsche Themenstarter:in
249 Beiträge seit 2009
vor 14 Jahren

Hm, dank für die Antwort

🤔
Ist für mich aber nicht so ganz einleuchtend (Ich habe kein Abiturabschluss oder so). Angenommen ich arbeite von 22:00 bis 6:00 Uhr. Das wäre eine Arbeitszeit von 8 Stunde. Nun ziehe ich davon die Startzeit des timeslots ab, also 7 Stunden.
Das ergäbe dann 1. Das ist zwar positiv und kleiner als 7:00 - 20:00 Uhr, aber diese Arbeitszeigt liegt nicht in diesem Zeitslot.
Ich bin da jetzt etwas verwirrt? Kannst du mir da nochmals auf die Sprünge helfen?
Vielen Dank!

Liebe Grüsse

Samuel

D
171 Beiträge seit 2008
vor 14 Jahren

Hallo Doltsche,

Du nimmst deine zwei Zeiten, und prüfst in dem du dir für einen Slot jeweis die Start und endzeitpunkte als Datetime für den gewünschten Tag anlegst, ob deine beieden Zeiten jeweils größes als die untergrenze, bzw. kleiner als die Obergrenze sind.
Ist das der Falls, dann rechnest du zeit2-zeit1 und hast ein TimeSpan.
Ist sagen wir Zeit2 größer, also geht über einen Slot hinweg, dann nimmst du Maxzeit-zeit1
Ist Zeit1 Kleiner nimmst du Zeit2-Minzeit.

Über zwei Tage hinweg kommt noch ein bischen was hinzu.

Gelöschter Account
vor 14 Jahren

(Ich habe kein Abiturabschluss oder so).

das macht nichts. habe ich auch nciht.

Angenommen ich arbeite von 22:00 bis 6:00 Uhr

dann liegt die startzeit 22:00 uhr - 07:00 uhr über dem tageszeitslot von 07:00 uhr bis 20:00 uhr da : "22:00 - 07:00 > 20:00 - 07:00" ( mit "-" ist hier das mathematische "minus" gemeint und nicht dsa gramatikalische "bis" )

@Daniel83:
so würde ich es nicht machen, da das sonst sie abfragen komplizierter werden.

D
Doltsche Themenstarter:in
249 Beiträge seit 2009
vor 14 Jahren

Hallo zusammen

Lange Zeit ist vergangen.
Ich habe nun etwas versucht zu machen, bin aber total überfordert dabei.

            DateTime start0720;
            TimeSpan TimeRest0720 = new TimeSpan(0,0,0);
            TimeSpan TimeIn0720 = new TimeSpan(0,0,0); 

            start0720 = start.Subtract(new TimeSpan(7,0,0));

            if (start0720.Hour <= 7)
            {
                TimeIn0720 = end - start; //end muss irgendwie durch 20 ersetzt werden
                if (TimeIn0720 > new TimeSpan(20 - 7, 0, 0))
                    TimeRest0720 = TimeIn0720.Subtract(new TimeSpan(20 - 7, 0, 0));
                TimeIn0720 = TimeIn0720.Subtract(TimeRest0720);
            }

Bis jetzt lässt sich damit der Zeitslot 07:00 Uhr - 20:00 Uhr berechnen.
Die Variablen start und end sind vom Typ DateTime und werden beim Funktiosaufruf übergeben. Sie enthalten die Zeit des Arbeitsbeginns bzw. des Arbeitsende.

Da ich nicht weis, wie ich eine "DateTime von einem bestimmten Wert subtrahiere", ist vorausgesetzt, dass die Variable end die Zeit 20:00 Uhr enthält.

Im weiteren ist mir noch unklar wie ich die Kombination mit den anderen Zeitslots anstellen soll. Ich bin hier etwas am verzweifeln. Bereits für die Umsetzung der obigen Funktion habe ich über 1.5 Stunden gebraucht...

Ich hoffe Ihr könnt mir weiterhelfen.
Vielen Dank bereits im Voraus.

LG Samuel

N
203 Beiträge seit 2008
vor 14 Jahren
            DateTime start = new DateTime(2010, 1, 4, 7, 30, 00); // 2010-01-04 7:30
            DateTime stop = new DateTime(2010, 1, 4, 12, 30, 00); // 2010-01-04 12:30

            TimeSpan arbeitszeit = stop.Subtract(start);

            Console.WriteLine(string.Concat("Arbeitszeit: ", arbeitszeit.Hours, " Stunden und ", arbeitszeit.Minutes, " Minuten."));
            // Arbeitszeit: 5 Stunden und 0 Minuten.

Ich bin heute morgen um 7:30 angefangen und werde um 12:30 in die Mittagspause gehen. Bis dahin werde ich 5 Std gearbeitet haben.

Die Arbeitszeit heute nach Mittag, kann ich einfach als zusätzlichen TimeSpan ausrechnen und dann mit dem TimeSpan arbeitszeit von heute Vormittag addieren. So habe ich die Arbeitszeit für den ganzen Tag errechnet.

Signatur.Text = "Greetz, Neals";

D
Doltsche Themenstarter:in
249 Beiträge seit 2009
vor 14 Jahren

Hallo Neals

Danke für deine Antwort.
Ich will dir nicht zuvorkommen, allerdings kann ich hier den Zusammenhang zu meinem Problem nicht ganz finden 🤔.

LG Samuel

N
203 Beiträge seit 2008
vor 14 Jahren

Habe ich da etwas falsch verstanden? Dann tut es mir leid. Du wolltest doch Arbeitszeiten berechnen, oder nicht?

Mit den zwei DateTime's lässt sich zwischen beliebigen Zeitpunkten die Differenz berechnen, auch wenn Tage dazwischen liegen oder über Mitternacht hinnaus gearbeitet wurde.

Die Differenz erhältst du als TimeSpan, von dem du dir die Zeitspanne einfach ausgeben lassen kannst, aber auch verschiedene Zeitspannen miteinander addieren kannst.

Um deine Einteilung in Slots zu ermöglichen, musst du halt die start und stop-Zeiten abfragen, wie du das auch schon angefangen hast.

Hier mal ein Beispiel, speziell welche auch über eine Nacht hinweg rechnet.


        static void Main(string[] args)
        {
            DateTime start = new DateTime(2010, 1, 4, 19, 45, 00); // 2010-01-04 7:30
            DateTime stop = new DateTime(2010, 1, 5, 13, 15, 00); // 2010-01-05 13:15
            
            double lohn = 0;

            while (start.CompareTo(stop) == -1)
            {
                DateTime end;
                int lohnProStunde; // Euro/Stunde

                // Slot 0 - 7 Uhr
                if (start.Hour >= 0 && start.Hour < 7)
                {
                    end = new DateTime(start.Year, start.Month, start.Day, 7, 0, 0);
                    lohnProStunde = 10;
                }
                    // Slot 7 - 18 Uhr
                else if (start.Hour >= 7 && start.Hour < 18)
                {
                    end = new DateTime(start.Year, start.Month, start.Day, 18, 0, 0);
                    lohnProStunde = 8;
                }
                    // Slot 18 - 24 Uhr
                else if (start.Hour >= 18 && start.Hour < 24)
                {
                    end = new DateTime(start.Year, start.Month, start.Day+1, 0, 0, 0);
                    lohnProStunde = 9;
                }
                // Fehler
                else
                {
                    throw new Exception("Der Tag hat nur 24 Std");
                }

                double hours = TimeDiff(start, end);

                lohn += hours * lohnProStunde;

                start = end;

                Console.WriteLine(lohn);
            }

            Console.ReadLine();
        }

        private static double TimeDiff(DateTime start, DateTime end)
        {
            TimeSpan span = end.Subtract(start);

            return ((double)span.Hours) + ((double)span.Minutes) / 60.0;
        }

Signatur.Text = "Greetz, Neals";

D
Doltsche Themenstarter:in
249 Beiträge seit 2009
vor 14 Jahren

Super, vielen Dank Neals 😉
Damit sollte ich weiterkommen =)

LG Samuel

D
Doltsche Themenstarter:in
249 Beiträge seit 2009
vor 14 Jahren

Hm, nun stellt sich mir doch noch eine Frage: Was wenn das Startdatum vom Enddatum abweicht. D.h. ich müsste die Zeit über mehrere Tage hinweg rechnen können. Nehmen wir an der Arbeitsbeginn ist 23.01.2010 23:00 Uhr und das Arbeitsende ist der 24.01.2010 05:00 Uhr.
Hat mir da evtl. Jemand eine Idee wie ich das angehen soll.

Schonmal Vielen Dank

LG Samuel

N
203 Beiträge seit 2008
vor 14 Jahren

Hast du den oben von mir geposteten Code mal ausprobiert?

Der rechnet auch über mehrere Jahre hinweg, da der start immer mit end überschrieben wird. In der while-Schleife wird solange gerechnet, bis start später oder gleich dem stop-Zeitpunkt ist, also auch über mehrere Tage hinweg.

Signatur.Text = "Greetz, Neals";

D
Doltsche Themenstarter:in
249 Beiträge seit 2009
vor 14 Jahren

Hallo Neals

Ja, den oberen Code habe ich bereits erweitert und eingefügt.
Interessanterweise geht es nun mit derm Verzug von einem Tag.
Bei den Werten 22.01.2010 08:00 Bis 23.02.2010 13:00 kommt jedoch folgende Fehlermeldung:

Die Parameter "Year", "Month", und "Day" beschreiben eine nicht darstellbare DateTime.

Woran könnte das liegen?

LG Samuel

P.s: Danke nochmals für deinen Code 😉.

49.485 Beiträge seit 2005
vor 14 Jahren
N
203 Beiträge seit 2008
vor 14 Jahren

Bei den Werten 22.01.2010 08:00 Bis 23.02.2010 13:00 kommt jedoch folgende Fehlermeldung:

Die Parameter "Year", "Month", und "Day" beschreiben eine nicht darstellbare DateTime.

Das liegt an dem Abschnitt

else if (start.Hour >= 18 && start.Hour < 24)
                {
                    end = new DateTime(start.Year, start.Month, start.Day+1, 0, 0, 0);
                    lohnProStunde = 9;
                }

in der Zeile

end = new DateTime(start.Year, start.Month, start.Day+1, 0, 0, 0);

wird start.Day+1 genommen... falls du aberden Monat wechselst, muss da start.Month+1, weil der Monat sicherlich keine 32 Tage hat 😉

Signatur.Text = "Greetz, Neals";

D
Doltsche Themenstarter:in
249 Beiträge seit 2009
vor 14 Jahren

Hallo Neals

Ich danke dir Vielmals für die Antwort 😉.

LG Samuel

D
91 Beiträge seit 2005
vor 12 Jahren

Ich weiß nicht, ob das Thema noch jemanden interessiert. Falls ja, kann ich euch wärmstens die Time Period Library empfehlen.

Hinweis von herbivore vor 12 Jahren

Alternativer Link: Time Period Library