Question

I am fetching the attendance details of employees in a datatable . It looks like this

Day       SwipeTime
12/31/2012  11AM
12/31/2012  1PM
12/31/2012  7PM
12/31/2012  8PM
1/1/2012    2PM
1/1/2012    7PM
1/1/2012    8PM
1/2/2012    10AM
1/2/2012    8PM

I need to display the date and totalhours for an employee where totalhours = lastswipe - firstwipe

my result would look like

Day TotalHours
12/31/2012  9
1/1/2012    6
1/2/2012    12

So i need to find min and max swipes grouped by date. Please help me write the query

Était-ce utile?

La solution

You can use Enumerable.GroupBy to group by date. Then you could create a Dictionary<DateTime,int> where the key is the date and the value are the total-hours for that date:

Dictionary<DateTime,int> dateGroups = table.AsEnumerable()
    .GroupBy(r => r.Field<DateTime>("Date").Date)
    .Select(g => new{
        Date = g.Key, 
        TotalHours = g.Sum(r => 
               DateTime.ParseExact(r.Field<string>("SwipeTime"), 
                      "htt", CultureInfo.InvariantCulture).Hour)
    }).ToDictionary(x => x.Date, x => x.TotalHours);

Edit: So, that was the TotalHours of the whole day, now the desired max-min calculation. You also have changed your desired timespan-format to "11:41 AM". Then i would use DateTime.Parse(str).TimeOfDay to get the timespan.

Dictionary<DateTime, int> dateGroups = table.AsEnumerable()
.GroupBy(r => r.Field<DateTime>("Date").Date)
.Select(g => new
{
    Date = g.Key,
    TotalHours = 
       (g.Max(r => DateTime.Parse(r.Field<string>("SwipeTime")).TimeOfDay)
      - g.Min(r => DateTime.Parse(r.Field<string>("SwipeTime")).TimeOfDay)).Hours
}).ToDictionary(x => x.Date, x => x.TotalHours);

Autres conseils

In this answer ordered list of times for day is created to avoid two things - parsing all rows twice, and creating two sets from parsed values to get max and min item. Also I do not parse day before grouping, because same date will have same string value.

var query = from row in table.AsEnumerable()
            group row by row.Field<string>("Day") into g
            let times = g.Select(r => DateTime.Parse(r.Field<string>("SwipeTime")))
                         .OrderBy(t => t.TimeOfDay)
                         .ToList()
            select new
            {
                DateTime.Parse(g.Key).Date,
                (times.Last() - times.First()).TotalHours
            };

Result is a collection of anonymous objects with two properties DateTime Date and double TotalHours

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top