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
Berechnung des Lohns
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 😃
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
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.
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
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.
(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.
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
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";
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
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";
Super, vielen Dank Neals 😉
Damit sollte ich weiterkommen =)
LG Samuel
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
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";
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 😉.
Hallo Doltsche,
siehe Zeitberechung in C#: Stunden addieren, aber nur zwischen 8:00 und 16:30
herbivore
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";
Hallo Neals
Ich danke dir Vielmals für die Antwort 😉.
LG Samuel
Ich weiß nicht, ob das Thema noch jemanden interessiert. Falls ja, kann ich euch wärmstens die Time Period Library empfehlen.
Alternativer Link: Time Period Library