我如何才能找到准确的工作时间在一天和休息时间在一天?

3vpjnl9f  于 2021-06-21  发布在  Mysql
关注(0)|答案(1)|浏览(535)

我有一天的休息时间和工作时间,我如何才能找到一天的确切工作时间和休息时间?
上班时间是这样的

以前我只有一个场景,比如7月2日,在这种情况下,我把休息时间转换成小时,然后直接从工作时间中扣除。

  1. $secondsPerHour = 3600;
  2. // Getting break entries
  3. $breakTimeEntries = TimeEntries::select('start_date', 'start_time', 'end_time', 'hour_type')
  4. ->where('hour_type', 'break')
  5. ->orderBy('start_date')->get();
  6. $breakDurationPerDayArray = array();
  7. // Looping through all the break entries and getting the break entries for each day
  8. foreach($breakTimeEntries as $breakTimeEntry) {
  9. $startDate = $breakTimeEntry->start_date;
  10. $breakStartTime = $breakTimeEntry->start_time;
  11. $breakEndTime = $breakTimeEntry->end_time;
  12. $breakHours = $breakEndTime - $breakStartTime;
  13. $breakHoursInSeconds = $breakHours/$secondsPerHour;
  14. // Adding the break entry for the day to array
  15. $breakTimePerDayArray[$startDate] = $breakHoursInSeconds;
  16. }
  17. // Getting work entries
  18. $breakTimeEntries = TimeEntries::select('start_date', 'start_time', 'end_time', 'hour_type')
  19. ->where('hour_type', 'work')
  20. ->orderBy('start_date')->get();
  21. $workAndBreakHoursArray = array();
  22. // Looping through all the work entries and getting the actual work entries for each day
  23. foreach($breakTimeEntries as $breakTimeEntry) {
  24. $workStartTime = $workTimeEntry->start_time;
  25. $workEndTime = $workTimeEntry->end_time;
  26. $workHours = $workEndTime - $workStartTime;
  27. $workHoursInSeconds = $breakHours/$secondsPerHour;
  28. $startDate = $breakTimeEntry->start_date;
  29. // Checking wether the start date is in array
  30. if(in_array($startDate, $breakDurationPerDayArray)) {
  31. $breakHoursInSeconds = $breakDurationPerDayArray[$startDate];
  32. $actualWorkedHours = $workHoursInSeconds - $breakHoursInSeconds;
  33. //To get the worked hours in minutes
  34. $actualWorkedHoursInMins = $actualWorkedHours/$secondsPerHour;
  35. //To get the break hours in minutes
  36. $breakHoursInMin = $breakHoursInSeconds/$secondsPerHour;
  37. $workAndBreakHoursArray[$startDate] = ['worked_hours' => $actualWorkedHoursInMins, 'break_hours' => $breakHoursInMin];
  38. } else {
  39. //To get the worked hours in minutes
  40. $workHoursInMins = $workHoursInSeconds/$secondsPerHour;
  41. $workAndBreakHoursArray[$startDate] = ['worked_hours' => $workHoursInMins, 'break_hours' => 0];
  42. }
  43. }

此时此刻我已经没有主意了。任何人都建议最好的处理方法。
预期产量是这样的,以小时为单位

  1. [
  2. [2018-07-02] => [Work => 8, Break =>1],
  3. [2018-07-03] => [Work => 8, Break =>1],
  4. [2018-07-04] => [Work => 8, Break =>1],
  5. [2018-07-05] => [Work => 3.5, Break =>0.5],
  6. [2018-07-06] => [Work => 4.5, Break =>0.5],
  7. [2018-07-09] => [Work => 3.5, Break =>0.5],
  8. [2018-07-10] => [Work => 4.5, Break =>0.5]
  9. ]

数据库链接

5n0oy7gb

5n0oy7gb1#

你给拉威尔贴了标签,所以我猜你在用它。它包含了碳,它是一个伟大的工具,一切与时间有关。https://carbon.nesbot.com/docs/#difference
edit1:下面是一个示例,假设您规范化了条目:

  1. $entries = [
  2. [
  3. 'type' => 'work',
  4. 'start' => 1310198400,
  5. 'end' => 1310230800,
  6. ],
  7. [
  8. 'type' => 'break',
  9. 'start' => 1310212800,
  10. 'end' => 1310216400,
  11. ],
  12. [
  13. 'type' => 'work',
  14. 'start' => 1310284800,
  15. 'end' => 1310299200,
  16. ],
  17. [
  18. 'type' => 'break',
  19. 'start' => 1310299200,
  20. 'end' => 1310302800,
  21. ],
  22. [
  23. 'type' => 'work',
  24. 'start' => 1310302800,
  25. 'end' => 1310317200,
  26. ],
  27. [
  28. 'type' => 'work',
  29. 'start' => 1310371200,
  30. 'end' => 1310385600,
  31. ],
  32. [
  33. 'type' => 'break',
  34. 'start' => 1310384700,
  35. 'end' => 1310387400,
  36. ],
  37. [
  38. 'type' => 'work',
  39. 'start' => 1310387400,
  40. 'end' => 1310403600,
  41. ]
  42. ];
  43. $workEntries = collect();
  44. $breakEntries = collect();
  45. foreach ($entries as $entry)
  46. {
  47. if ($entry['type'] == 'work')
  48. $workEntries->push($entry);
  49. else if ($entry['type'] == 'break')
  50. $breakEntries->push($entry);
  51. }
  52. /*
  53. For each work entry, check if any break entry overlaps.
  54. * /
  55. foreach ($workEntries as $workEntry)
  56. {
  57. $workStart = $workEntry['start'];
  58. $workEnd = $workEntry['end'];
  59. foreach ($breakEntries as $breakEntry)
  60. {
  61. $breakStart = $breakEntry['start'];
  62. $breakEnd = $breakEntry['end'];
  63. $overlapDuration = 0;
  64. if (!Carbon::createFromTimestamp($workStart)->isSameDay(Carbon::createFromTimestamp($breakStart)))
  65. continue;
  66. /*
  67. Check if work and break overlap
  68. Scenario 1:
  69. Break started mid-work
  70. Scenario 2:
  71. Break started before work
  72. */
  73. if (($breakStart >= $workStart) || ($breakStart < $workStart))
  74. {
  75. if ($breakStart >= $workStart)
  76. $overlapStart = $breakStart;
  77. else if ($breakStart < $workStart)
  78. $overlapStart = $workStart;
  79. /*
  80. Break ends before work ends (or simultaneously)
  81. */
  82. if ($breakEnd <= $workEnd)
  83. $overlapEnd = $breakEnd;
  84. /*
  85. Break ends after work ends
  86. */
  87. else
  88. $overlapEnd = $workEnd;
  89. /*
  90. Calculate overlap length
  91. */
  92. $overlapDuration = $overlapEnd - $overlapStart;
  93. }
  94. /*
  95. Actual time worked that day is time worked - breaks that overlap work periods.
  96. Get human-friendly date (day, month, year), display.
  97. */
  98. $workDuration = ($workEnd - $workStart - $overlapDuration)/3600;
  99. $date = Carbon::createFromTimestamp($workStart)->toFormattedDateString();
  100. dump("Time worked on $date is $workDuration h.");
  101. }
  102. }

将打印:

  1. "Time worked on Jul 9, 2011 is 8 h."
  2. "Time worked on Jul 10, 2011 is 4 h."
  3. "Time worked on Jul 10, 2011 is 4 h."
  4. "Time worked on Jul 11, 2011 is 3.75 h."
  5. "Time worked on Jul 11, 2011 is 4.5 h."

我假设对每天的数据进行分组不会带来太多麻烦:)
edit2:在我做一个工作示例之前,我没有注意到你更改了你的问题,所以请原谅数据没有按你想要的格式显示。再说一次,让它符合你的需要应该是一项简单的任务。

展开查看全部

相关问题