Autor Beitrag
lapadula
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 180
Erhaltene Danke: 10



BeitragVerfasst: Fr 29.06.18 14:47 
Hallo, ich bräuchte einen Schubs in die richtige Richtung bei dem folgenden Problem.

Ich habe eine Liste mit Objekten. Das Object hat unter anderem die Eigenschaft vom Datentyp DateTime und eine Eigenschaft mit dem Datentyp Integer.

Es handelt sich dabei um alle Zeitstempel eines Mitarbeiters.

So sieht die Tabelle aus:

01.01.2018 08:00 - 0 Eingestempelt
01.01.2018 12:00 - 1 Ausgestempelt
01.01.2018 12:30 - 0
01.01.2018 17:00 - 1

02.01.2018 08:00 - 0
02.01.2018 12:30 - 1
02.01.2018 13:00 - 0
02.01.2018 17:00 - 1

Diese ganzen Zeiten habe ich wie gesagt in ner List und möchte nun ausrechnen wie viel Minuten insgesamt gearbeitet wurde.
Bei der oberen Tabelle wären es 4 Std + 4 Std 30 Min = 7,5 Std. (von 8 - 12, 30 Min Pause, von 12:30 bis 17 Uhr).

Dann kommen die Stempel vom 02.01. dazu usw.

Ich verstricke mich gerade hier mit Schleifen und Hilfslisten, wo mich mich frage ob das eleganter geht.

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
 List<Stempel> listeEingestempelt = new List<Stempel>();
            List<Stempel> listAusgestempelt = new List<Stempel>();

            foreach (Stempel stempel in listAlleStempelVomBenutzer)
            {
                if (timeMotoStempel.INOUT == 0 || timeMotoStempel.INOUT == 1)
                {
                    if (stempel.INOUT == 0)
                    {
                        listeEingestempelt.Add(stempel);
                    }
                    else if (stempel.INOUT == 1)
                    {
                        listAusgestempelt.Add(stempel);
                    }
                }
            }

var GesamtMinuten = 0;
            var counter = 0;
            foreach (Stempel eingestempelt in listeEingestempelt)
            {
                TimeSpan span = listAusgestempelt[counter].WHEN.Subtract(eingestempelt.WHEN);
                var differenz = span.TotalMinutes;
                GesamtMinuten += differenz;
                counter += 1;
            }


INOUT ist hier der eingestempelt/ausgestempelt indikator (0 oder 1)
WHEN ist hier das Datum wann es geschehen ist.

So in etwa, nur das ich den Wechsel der Tage noch berücksichtigen muss.

Kann mir jemand helfen


Zuletzt bearbeitet von lapadula am Fr 29.06.18 15:48, insgesamt 1-mal bearbeitet
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4706
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Fr 29.06.18 15:13 
Korrigiere bitte dein Beispiel. Oder erkläre genauer was du sagen willst mit dem Beispiel.
Du sagst er hat zwischen 12:30-17:00 gearbeitet hat, nach deinem Beispiel sind beides aber Einstempel-Vorgänge.
Für mich hat der man von 12:30 bis 12:30 am nächsten Tag durchgearbeitet da er dazwischen nur eingestempelt hat.

Für diesen Beitrag haben gedankt: lapadula
lapadula Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 180
Erhaltene Danke: 10



BeitragVerfasst: Fr 29.06.18 15:49 
Sorry, hab’s korrigiert.
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 29.06.18 16:31 
- Nachträglich durch die Entwickler-Ecke gelöscht -

Für diesen Beitrag haben gedankt: lapadula
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4706
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Fr 29.06.18 18:22 
Eleganz ist so eine Sache. Es sollte etwas sein das du und deine Kollegen auch nachvollziehen können und die Korrektheit entsprechend testen könnt.
Elegant wäre eine Linq Lösung. Ob die aber auch nachvollziehbar/testbar/performant ist ist eine andere Sache.
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
static void Main(string[] args)
{
    var testData = new List<Stempel>()
    {
        new Stempel { WHEN = new DateTime(201811,  8,  00), INOUT = 0 },
        new Stempel { WHEN = new DateTime(20181112,  00), INOUT = 1 },
        new Stempel { WHEN = new DateTime(20181112300), INOUT = 0 },
        new Stempel { WHEN = new DateTime(20181117,  00), INOUT = 1 },
        new Stempel { WHEN = new DateTime(201812,  8,  00), INOUT = 0 },
        new Stempel { WHEN = new DateTime(20181212300), INOUT = 1 },
        new Stempel { WHEN = new DateTime(20181213,  00), INOUT = 0 },
        new Stempel { WHEN = new DateTime(20181217,  00), INOUT = 1 },
    }.OrderBy(x => x.WHEN);

    var workingMinutes = testData
                            .Where(x => x.INOUT == 0)
                            .Select(x => testData.SkipWhile(y => y.WHEN <= x.WHEN).First(z => z.INOUT == 1).WHEN - x.WHEN)
                            .Sum(x=> x.TotalMinutes);
              
    Console.WriteLine(workingMinutes);    
}

public class Stempel
{
  public DateTime WHEN { get; set; }
  public int INOUT { get; set; }
}


Diese Linq Lösung hätte z.B. Probleme wenn die Liste nicht sortiert ist, oder die Liste mit einem einstempeln endet, oder wenn einstempeln-ausstempeln sich nicht sauber abwechseln, oder wenn einstempeln-ausstempeln zeitgleich stattfindet .....

Ein gute Lösung ist hier sicherlich nur möglich wenn man alle zu berücksichtigen Details kennt. Eine scheinbar elegante Lösung wird sonst schnell zu offensichtlichem Mist.

Für diesen Beitrag haben gedankt: lapadula
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Fr 29.06.18 22:04 
Moin!

Ich hab ich auch mal mit sowas rumgeschlagen, hier noch ein paar Tipps von mir dazu ;) vielleicht hilft´s was :nixweiss:
  • Ich habe damals EINstempeln mit +1 und AUSstempeln mit -1 abgebildet. Wenn du die Summe der Datensätze über die Spalte "Stempelart" bildest, muss sie wieder 0 sein, damit ein Tag komplett abgedeckt ist. :idea:
  • ich hatte mich damals für einen separaten Datensatztyp "Pause" entschieden, der mit 0 getagged ist, so dass er die EIN/AUS-Summe nicht beeinflusst und negativ auf die Zeitensumme angerechnet wird; so konnte man simpel eine "irgendwann" stattgefundene Pause erfassen
  • Beim Erfassen habe ich bereits sichergestellt, dass man nur "von innen nach aussen" Datensätze hinzufügen kann, also sagen wir mal der erste Datensatz am Tag ist EIN:0900, dann kann man den nächsten Datensatz nur mit AUS>0900 oder AUS<0900 erfassen; wir erfassen mal einfach AUS:1200. Jetzt kann man nur EIN>1200 oder AUS<0900 erfassen, usw.
  • Um einen vollständigen Tag abzurechnen, muss der erste Datensatz ein +1 markierter sein = EINstempeln
cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.

Für diesen Beitrag haben gedankt: lapadula
lapadula Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 180
Erhaltene Danke: 10



BeitragVerfasst: Sa 30.06.18 12:58 
Danke für die Antworten.

Also wir nutzen ein neues Zeiterfassungssysten, mit der dazugehöriger Software. Allerdings zeigt diese nicht wirklich die aktuellen Stunden an, bzw. rechnet das intransparen.

Deswegen soll ich es machen, indem ich auf die Datenbank zugreifen und selber nachrechne.