2016-07-26 2 views
1

Ich habe ein Problem, erste Eintrag und letzten Eintrag auf die biometrische Lesung erhalten, wenn es den folgenden Tag überschreitet, wenn der Benutzer Zeit aus. Aber wenn die Zeit in und Auszeit am selben Tag ist kann ich es die Art und Weise formatiert ich will ..Das erste Mal-In und das letzte Time-Out für den folgenden Tag basierend auf einem Datum Sammlung mit linq

hier ist mein Code:

 IEnumerable<biometric> dtrs = new List<biometric>() 
     { 
      new biometric{Id = 1, InOut = 0, DateTime = new DateTime(2013,5,5,8,0,0)}, 
      new biometric{Id = 2, InOut = 0, DateTime = new DateTime(2013,5,5,8,0,5)}, 
      new biometric{Id = 3, InOut = 0, DateTime = new DateTime(2013,5,5,8,1,0)}, 
      new biometric{Id = 4, InOut = 0, DateTime = new DateTime(2013,5,5,8,2,0)}, 

      //here is my problem getting this paired to 
      new biometric{Id = 5, InOut = 0, DateTime = new DateTime(2013,5,5,18,0,0)}, 

      new biometric{Id = 1, InOut = 1, DateTime = new DateTime(2013,5,5,18,0,0)}, 
      new biometric{Id = 2, InOut = 1, DateTime = new DateTime(2013,5,5,17,5,5)}, 
      new biometric{Id = 3, InOut = 1, DateTime = new DateTime(2013,5,5,17,5,10)}, 
      new biometric{Id = 4, InOut = 1, DateTime = new DateTime(2013,5,5,17,10,0)}, 

      //this Entry here 
      new biometric{Id = 5, InOut = 1, DateTime = new DateTime(2013,5,6,3,0,0)}, 
     }; 

     var asd = dtrs.GroupBy(x => new { x.Id, x.DateTime.Date }, (key, group) => new 
     { 
      Key1 = key.Date, 
      Key2 = key.Id, 
      Result = group.OrderBy(a => a.DateTime).ToList() 
     }) 
     //checks if the grouping result has one timein and 1 timeout or more 
     .Where(a => a.Result.Where(z => z.InOut == 1).Count() >= 1 && a.Result.Where(z => z.InOut == 0).Count() >= 1) 
     .Select(a => new dtr() { employeeId = a.Key2, TimeIn = a.Result.FirstOrDefault(b => b.InOut == 1).DateTime, TimeOut = a.Result.LastOrDefault(c => c.InOut == 0).DateTime }); 



    private class biometric 
     { 
     public int Id { get; set; } 
     public DateTime DateTime { get; set; } 
     public int InOut { get; set; } 
     } 

     private class dtr 
     { 
     public int employeeId { get; set; } 
     public DateTime TimeIn { get; set; } 
     public DateTime TimeOut { get; set; } 
     } 

ich diesen
neuen biometrischen koppeln möchten {Id = 5, InOut = 0, Datetime = new Datetime (2013,5,5,18,0,0)}

dieser
neuen biometrischen {id = 5, InOut = 1, Datetime = new DateTime (2013,5,6,3,0,0)},

jede Problemumgehung oder Vorschläge ??

+0

kannst du nicht einfach Gruppe von 'Id' und Ordnung von' InOut'? –

+0

nein .. wurden es pro Tag und am folgenden Tag auch –

Antwort

1

Ich fügte einen zweiten Tag Daten hinzu, um sicherzustellen, dass die Filterung richtig war. Dies setzt voraus, dass niemand mehr als 18 Stunden an einem Tag arbeitet. Unter der Annahme, dass die meisten Menschen einen Standard 8 Stunden arbeiten, könnte das bis zu 31 Stunden eingestellt werden.

employeeId TimeIn       TimeOut 
1   05/05/2013 08:00:00.000   05/05/2013 18:00:00.000 
2   05/05/2013 08:00:05.000   05/05/2013 17:05:05.000 
3   05/05/2013 08:01:00.000   05/05/2013 17:05:10.000 
4   05/05/2013 08:02:00.000   05/05/2013 17:10:00.000 
5   05/05/2013 18:00:00.000   05/06/2013 03:00:00.000 
1   05/06/2013 08:00:00.000   05/06/2013 18:00:00.000 
2   05/06/2013 08:00:05.000   05/06/2013 17:05:05.000 
3   05/06/2013 08:01:00.000   05/06/2013 17:05:10.000 
4   05/06/2013 08:02:00.000   05/06/2013 17:10:00.000 
5   05/06/2013 18:00:00.000   05/07/2013 03:00:00.000 

Auch als eine Randnotiz, Ihre Original-Code enthalten a.Result.Where(z => z.InOut == 1).Count() >= 1. Das könnte auf reduziert werden, was, abgesehen davon, dass es übersichtlich ist, würde es wahrscheinlich schneller ausgeführt werden.

UPDATE: diese beiden Datensätze Hinzufügen (Employee 1 geht zum Mittagessen)

 new biometric{Id = 1, InOut = 1, DateTime = new DateTime(2013,5,5,12,0,0)}, 
     new biometric{Id = 1, InOut = 0, DateTime = new DateTime(2013,5,5,13,0,1)}, 


var sorted = dtrs.OrderBy (d =>d.Id).ThenBy (d =>d.DateTime).ToList(); 

var zipped = sorted.Where (d =>d.InOut==0).Zip(sorted.Where (s =>s.InOut==1), 
       (i,o)=>{ 
         Debug.Assert(i.Id == o.Id); 
         return new dtr 
        { 
         employeeId = i.Id, 
         TimeIn=i.DateTime, 
         TimeOut= o.DateTime 
        }; 
       }).OrderBy (d =>d.TimeIn); 
zipped.Dump(); 
+0

mu upvote für alle ich habe nicht daran gedacht –

+0

diese Zeile hinzufügen neue biometrische {Id = 1, InOut = 0, DateTime = neue DateTime (2013,5,5,8,0,1)}, Erzeugt 6 Paare mit demselben Datum wie die Zeit, aber nur eine Minute später, kann also nicht als beantwortet markiert werden –

+0

Das würde erfordern, dass die Person zweimal ohne getaktet war Verlassen. Ich kann nicht verantwortlich sein, wenn Sie ungültige Daten eingeben. –

Verwandte Themen