fork(3) download
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4.  
  5. namespace TimeClock
  6. {
  7. class Program
  8. {
  9. static void Main()
  10. {
  11. var blockStart = new TimeSpan(0, 6, 0, 0);
  12. var blockEnd = new TimeSpan(0, 17, 0, 0);
  13.  
  14. var listOfTimeLogs = new List<TimeLog>
  15. {
  16. new TimeLog {EntryDateTime = new DateTime(2016,05,20,6,0,0),EntryType = EntryTypes.In},
  17. new TimeLog {EntryDateTime = new DateTime(2016,05,20,10,0,0),EntryType = EntryTypes.Out},
  18. new TimeLog {EntryDateTime = new DateTime(2016,05,20,10,15,0),EntryType = EntryTypes.In},
  19. new TimeLog {EntryDateTime = new DateTime(2016,05,20,12,0,0),EntryType = EntryTypes.Out},
  20. new TimeLog {EntryDateTime = new DateTime(2016,05,20,12,30,0),EntryType = EntryTypes.In},
  21. new TimeLog {EntryDateTime = new DateTime(2016,05,20,15,0,0),EntryType = EntryTypes.Out},
  22. new TimeLog {EntryDateTime = new DateTime(2016,05,20,15,15,0),EntryType = EntryTypes.In},
  23. new TimeLog {EntryDateTime = new DateTime(2016,05,20,18,00,0),EntryType = EntryTypes.Out}
  24. };
  25.  
  26.  
  27. // You are going to have have for / for each unless you use Linq
  28.  
  29. // fist I would count clock in's versus the out's
  30. var totalIn = listOfTimeLogs.Count(e => e.EntryType == EntryTypes.In);
  31. var totalOut = listOfTimeLogs.Count() - totalIn;
  32.  
  33. // check if we have in the number of time entries
  34. if (totalIn > totalOut)
  35. {
  36. Console.WriteLine("Employee didn't clock out");
  37. }
  38.  
  39. // as I was coding this sample program, i thought of another way to store the time
  40. // I would store them in blocks - we have to loop
  41. var timeBlocks = new List<TimeBlock>();
  42. for (var x = 0; x < listOfTimeLogs.Count; x += 2)
  43. {
  44. // create a new WORKING block based on the in/out time entries
  45. timeBlocks.Add(new TimeBlock
  46. {
  47. BlockType = BlockTypes.Working,
  48. In = listOfTimeLogs[x],
  49. Out = listOfTimeLogs[x + 1]
  50. });
  51.  
  52. // create a BREAK block based on gaps
  53. // check if the next entry in a clock in
  54. var breakOut = x + 2;
  55. if (breakOut < listOfTimeLogs.Count)
  56. {
  57. var breakIn = x + 1;
  58. // create a new BREAK block
  59. timeBlocks.Add(new TimeBlock
  60. {
  61. BlockType = BlockTypes.Break,
  62. In = listOfTimeLogs[breakIn],
  63. Out = listOfTimeLogs[breakOut]
  64. });
  65. }
  66. }
  67.  
  68. var breakCount = 0;
  69. // here is a loop for displaying detail
  70. foreach (var block in timeBlocks)
  71. {
  72. var lineTitle = block.BlockType.ToString();
  73. // this is me trying to be fancy
  74. if (block.BlockType == BlockTypes.Break)
  75. {
  76. if (block.IsBreak())
  77. {
  78. lineTitle = $"Break #{++breakCount}";
  79. }
  80. else
  81. {
  82. lineTitle = "Lunch";
  83. }
  84. }
  85. Console.WriteLine($" {lineTitle,-10} {block} === Length: {block.Duration.ToString(@"hh\:mm")}");
  86. }
  87.  
  88. // calculating total time for each block type
  89. var workingTime = timeBlocks.Where(b => b.BlockType == BlockTypes.Working)
  90. .Aggregate(new TimeSpan(0), (p, v) => p.Add(v.Duration));
  91.  
  92. var breakTime = timeBlocks.Where(b => b.BlockType == BlockTypes.Break)
  93. .Aggregate(new TimeSpan(0), (p, v) => p.Add(v.Duration));
  94.  
  95.  
  96. Console.WriteLine($"\nTotal Working Hours: {workingTime.ToString(@"hh\:mm")}");
  97. Console.WriteLine($" Total Break Time: {breakTime.ToString(@"hh\:mm")}");
  98.  
  99. Console.ReadLine();
  100. }
  101. }
  102.  
  103. public enum EntryTypes
  104. {
  105. In,
  106. Out
  107. }
  108.  
  109. public enum BlockTypes
  110. {
  111. Working,
  112. Break
  113. }
  114.  
  115. public class TimeBlock
  116. {
  117. public BlockTypes BlockType;
  118. public TimeLog In;
  119. public TimeLog Out;
  120.  
  121. public TimeSpan Duration
  122. {
  123. get
  124. {
  125. // TODO: Need error checking
  126. return Out.EntryDateTime.Subtract(In.EntryDateTime);
  127. }
  128. }
  129.  
  130. public override string ToString()
  131. {
  132. return $"In: {In.EntryDateTime:HH:mm} - Out: {Out.EntryDateTime:HH:mm}";
  133. }
  134.  
  135. }
  136.  
  137. // a little extension class
  138. public static class Extensions
  139. {
  140. public static bool IsBreak(this TimeBlock block)
  141. {
  142. // if the length of the break period is less than 19 minutes
  143. // we will consider it a break, the person could have clock IN late
  144. return block.Duration.TotalMinutes < 19 ? true : false;
  145.  
  146. }
  147.  
  148. }
  149.  
  150. public class TimeLog
  151. {
  152. public DateTime EntryDateTime;
  153. public EntryTypes EntryType;
  154. }
  155. }
  156.  
Success #stdin #stdout 0.09s 24248KB
stdin
Standard input is empty
stdout
 Working    In: 06:00 - Out: 10:00  ===  Length: 04:00
 Break #1   In: 10:00 - Out: 10:15  ===  Length: 00:15
 Working    In: 10:15 - Out: 12:00  ===  Length: 01:45
 Lunch      In: 12:00 - Out: 12:30  ===  Length: 00:30
 Working    In: 12:30 - Out: 15:00  ===  Length: 02:30
 Break #2   In: 15:00 - Out: 15:15  ===  Length: 00:15
 Working    In: 15:15 - Out: 18:00  ===  Length: 02:45

Total Working Hours: 11:00
   Total Break Time: 01:00