2016-05-21 4 views
2

Я надеюсь, что кто-то может помочь мне с оптимальным решением для этого. У меня есть список журналов времени. Он содержит запись данных для каждого часа на одного сотрудника в день.Расчет часов часов сотрудников

Я пытаюсь найти хорошее решение для расчета времени работы в день. Время, прошедшее между каждым часовым механизмом и тайм-аутом для одного сотрудника.

Окончательный результат должен дать мне следующее.

  • Общее время работал
  • Общее тайм-аут
  • Время, прошедшее между каждой строке журнала/извлекать и показывать время работал и тайм-аут.

Например ClockIn: 6:00 ClockedOut: 10:00 ClockedIn: 10:15

Breaktime = 00:15

и так далее.

Я стараюсь избегать использования для многих циклов цикла/foreach.

Это образец кода, представляющий список журналов времени. Тип есть. I = для Clock-In и O = Clock-Out. Каждый сдвиг имеет время начала блокировки и время окончания блока.

var blockStart = new TimeSpan(0,6,0,0,0); 
var blockEnd = new TimeSpan(0,17,0,0); 

var listOfTimeLogs = new List<TimeLog>() 
     { 
      new TimeLog() {EntryDateTime = new DateTime(2016,05,20,6,0,0),Type = "I"}, 
      new TimeLog() {EntryDateTime = new DateTime(2016,05,20,10,0,0),Type = "O"}, 
      new TimeLog() {EntryDateTime = new DateTime(2016,05,20,10,15,0),Type = "I"}, 
      new TimeLog() {EntryDateTime = new DateTime(2016,05,20,12,0,0),Type = "O"}, 
      new TimeLog() {EntryDateTime = new DateTime(2016,05,20,12,30,0),Type = "I"}, 
      new TimeLog() {EntryDateTime = new DateTime(2016,05,20,15,0,0),Type = "O"}, 
      new TimeLog() {EntryDateTime = new DateTime(2016,05,20,15,15,0),Type = "I"}, 
      new TimeLog() {EntryDateTime = new DateTime(2016,05,20,18,00,0),Type = "O"} 
     }; 

Надеюсь, что это имеет смысл. любая помощь будет оценена. Thank you

+1

порога вы застряли? Если всегда есть i, o, i, o ... pattern, вы можете сделать это за один проход. Дайте в результате, что вы ожидаете от этого ввода. –

ответ

1

Компьютеры предназначены для выполнения циклов.

Здесь sample, как бы я справился с этой проблемой.

Program.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 

namespace TimeClock 
{ 
    class Program 
    { 
     static void Main() 
     { 
      var blockStart = new TimeSpan(0, 6, 0, 0); 
      var blockEnd = new TimeSpan(0, 17, 0, 0); 

      var listOfTimeLogs = new List<TimeLog> 
      { 
       new TimeLog {EntryDateTime = new DateTime(2016,05,20,6,0,0),EntryType = EntryTypes.In}, 
       new TimeLog {EntryDateTime = new DateTime(2016,05,20,10,0,0),EntryType = EntryTypes.Out}, 
       new TimeLog {EntryDateTime = new DateTime(2016,05,20,10,15,0),EntryType = EntryTypes.In}, 
       new TimeLog {EntryDateTime = new DateTime(2016,05,20,12,0,0),EntryType = EntryTypes.Out}, 
       new TimeLog {EntryDateTime = new DateTime(2016,05,20,12,30,0),EntryType = EntryTypes.In}, 
       new TimeLog {EntryDateTime = new DateTime(2016,05,20,15,0,0),EntryType = EntryTypes.Out}, 
       new TimeLog {EntryDateTime = new DateTime(2016,05,20,15,15,0),EntryType = EntryTypes.In}, 
       new TimeLog {EntryDateTime = new DateTime(2016,05,20,18,00,0),EntryType = EntryTypes.Out} 
      }; 


      // You are going to have have for/for each unless you use Linq 

      // fist I would count clock in's versus the out's 
      var totalIn = listOfTimeLogs.Count(e => e.EntryType == EntryTypes.In); 
      var totalOut = listOfTimeLogs.Count() - totalIn; 

      // check if we have in the number of time entries 
      if (totalIn > totalOut) 
      { 
       Console.WriteLine("Employee didn't clock out"); 
      } 

      // as I was coding this sample program, i thought of another way to store the time 
      // I would store them in blocks - we have to loop 
      var timeBlocks = new List<TimeBlock>(); 
      for (var x = 0; x < listOfTimeLogs.Count; x += 2) 
      { 
       // create a new WORKING block based on the in/out time entries 
       timeBlocks.Add(new TimeBlock 
       { 
        BlockType = BlockTypes.Working, 
        In = listOfTimeLogs[x], 
        Out = listOfTimeLogs[x + 1] 
       }); 

       // create a BREAK block based on gaps 
       // check if the next entry in a clock in 
       var breakOut = x + 2; 
       if (breakOut < listOfTimeLogs.Count) 
       { 
        var breakIn = x + 1; 
        // create a new BREAK block 
        timeBlocks.Add(new TimeBlock 
        { 
         BlockType = BlockTypes.Break, 
         In = listOfTimeLogs[breakIn], 
         Out = listOfTimeLogs[breakOut] 
        }); 
       } 
      } 

      var breakCount = 0; 
      // here is a loop for displaying detail 
      foreach (var block in timeBlocks) 
      { 
       var lineTitle = block.BlockType.ToString(); 
       // this is me trying to be fancy 
       if (block.BlockType == BlockTypes.Break) 
       { 
        if (block.IsBreak()) 
        { 
         lineTitle = $"Break #{++breakCount}"; 
        } 
        else 
        { 
         lineTitle = "Lunch"; 
        } 
       } 
       Console.WriteLine($" {lineTitle,-10} {block} === Length: {block.Duration.ToString(@"hh\:mm")}"); 
      } 

      // calculating total time for each block type 
      var workingTime = timeBlocks.Where(b => b.BlockType == BlockTypes.Working) 
        .Aggregate(new TimeSpan(0), (p, v) => p.Add(v.Duration)); 

      var breakTime = timeBlocks.Where(b => b.BlockType == BlockTypes.Break) 
        .Aggregate(new TimeSpan(0), (p, v) => p.Add(v.Duration)); 


      Console.WriteLine($"\nTotal Working Hours: {workingTime.ToString(@"hh\:mm")}"); 
      Console.WriteLine($" Total Break Time: {breakTime.ToString(@"hh\:mm")}"); 

      Console.ReadLine(); 
     } 
    } 
} 

TimeBlock.cs

using System; 

namespace TimeClock 
{ 
    public enum BlockTypes 
    { 
     Working, 
     Break 
    } 

    public class TimeBlock 
    { 
     public BlockTypes BlockType; 
     public TimeLog In; 
     public TimeLog Out; 

     public TimeSpan Duration 
     { 
      get 
      { 
       // TODO: Need error checking 
       return Out.EntryDateTime.Subtract(In.EntryDateTime); 
      } 
     } 

     public override string ToString() 
     { 
      return $"In: {In.EntryDateTime:HH:mm} - Out: {Out.EntryDateTime:HH:mm}"; 
     } 

    } 

    // a little extension class 
    public static class Extensions 
    { 
     public static bool IsBreak(this TimeBlock block) 
     { 
      // if the length of the break period is less than 19 minutes 
      // we will consider it a break, the person could have clock IN late 
      return block.Duration.TotalMinutes < 19 ? true : false; 

     } 

    } 

} 

TimeLog.cs

using System; 

namespace TimeClock 
{ 
    public class TimeLog 
    { 
     public DateTime EntryDateTime; 
     public EntryTypes EntryType; 
    } 
} 

EntryTypes.cs

namespace TimeClock 
{ 
    public enum EntryTypes 
    { 
     In, 
     Out 
    } 
} 

Output of Program

+1

Черная лягушка - Большое спасибо за вход. очень признателен. Именно то, что мне нужно. – Bernardt

+0

Мне нравится небольшое добавление, которое вы добавили. Конечно, можно использовать это как часть правил, которые мне нужно реализовать для смен. – Bernardt

+0

Нет проблем и рада, что вам это нравится. –

Смежные вопросы