【问题标题】:Find minutes working alone [closed]寻找单独工作的时间[关闭]
【发布时间】:2017-12-21 05:03:20
【问题描述】:

我有工作人员的时间清单。我需要了解是否有员工单独工作,以及他们一天单独工作了多少分钟

| staff| start | end   |
|:---  |:---   |:---   |
| 1    | 11:05 | 20:00 | 
| 2    | 11:00 | 17:00 |
| 3    | 19:00 | 03:00 |
| 4    | 13:00 | 20:00 |
| 5    | 19:00 | 03:00 |

在 Andrea 的帮助下,下面是获取第一个和最后一个单独工作的人的代码,但它并不安静。因为如果有 3 个不同时间的人单独工作,就会出现问题。

$staff = array(1,2,3,4,5);
$start = array("11:05", "11:00", "19:00", "13:00", "19:00");
$end = array("20:00", "17:00", "03:00", "20:00", "03:05");

array_multisort($start, $end, $staff);

$aloneStart = (strtotime($start[1]) - strtotime($start[0]))/60; // first and second items are the ones that may be working alone at start
$aloneEnd = (strtotime($end[count($end)-1]) - strtotime($end[count($end)-2]))/60; // last and second to last are the ones that may be working alone at end
if($aloneStart > 0){
  $staffAloneStart = $staff[0]; //must be the first who worked alone  
  echo "minutes alone at start: " . $aloneStart . " and it was " . $staffAloneStart . "\n";
} 
if($aloneEnd > 0){
  $staffAloneEnd = $staff[count($end)-1]; // must be the last to end that worked alone  
  echo "minutes alone at end: " . $aloneEnd . " and it was " . $staffAloneEnd . "\n";
} 
$aloneTime = intval($aloneStart)+intval($aloneEnd);
echo "total time alone " . $aloneTime;

使用以下数组,您会看到第一个用户的分钟数需要超过 5 分钟,因为他在晚上更多地独自工作。

$staff = array(1, 2, 3, 4, 5);
$start = array("11:05", "11:10", "19:00", "13:00", "19:00");
$end = array("20:00", "17:00", "03:00", "16:00", "03:00");

【问题讨论】:

  • 是的:预计Stack Overflow users? 的研究工作量是多少
  • @RiggsFolly 我不需要解决方案,我只需要一些关于如何实施的指导。
  • 这是存储在数据库中,还是只是一个数组?
  • @Qirel 数据库,但是获取并制作成数组。

标签: php time schedule


【解决方案1】:

知道了!

花了一些时间,但我找到了解决方案。
它在数组中确实有一个额外的项目,但由于持续时间为零,它不应该引起问题。

$staff = array(1,2,3,4,5);
$start = array("11:05", "11:00", "19:00", "13:00", "19:00");
$end = array("16:00", "17:00", "03:00", "16:00", "03:05");

// Add staff number to end of time ex 11:00 => 11:00#2
For($i=0; $i<count($start);$i++){
    $start[$i] .= "#" . $staff[$i];
    $end[$i] .= "#" . $staff[$i];

}
$t = array_merge($start,$end); // create one long array with all in and out times
sort($t);

// Multisport is needed to get all arrays in time order as reference
array_multisort($start, $end, $staff);

// Find first start time (11:00) and slice array thwre, build string
$test = implode(PHP_EOL,array_slice($t, array_search($start[0], $t)));

// Find the times before first start (night end times) and add them last in string
$test .= PHP_EOL . implode(PHP_EOL,array_slice($t, 0,array_search($start[0], $t)));
$times = explode(PHP_EOL, $test); // explode to make it array again
 // Var_dump($times);

$WhoIsInDaHouse = array("dummy"); // add a dummy variable since 0=false in later if
$j=0;
for($i=0; $i<count($times);$i++){
    $TimePerson = explode("#", $times[$i]);
    $Time = $TimePerson[0];
    $person = $TimePerson[1];


    $inout = array_search($person, $WhoIsInDaHouse); //is person in house and about to leave?
    If($inout != false){ //if person enter work false, if true: key of person leaving in $WhoIsInDaHouse
        //Here $person is leaving work
        Unset($WhoIsInDaHouse[$inout]);

        If(count($WhoIsInDaHouse) == 2){ // someone will now be alone since we have a dummy
            $Alone[$j]["start"] = $Time;
            $Alone[$j]["who"] = array_slice($WhoIsInDaHouse, -1)[0];
        }elseif(count($WhoIsInDaHouse) == 1 && $prevcount == 2){
            // Only dummy left
            $Alone[$j]["end"] = $Time;
            $Alone[$j]["duration"] = strtotime($Alone[$j]["end"])-strtotime($Alone[$j]["start"]);
            $j++;
        }
    }Else{
        // Here person enters work
        $WhoIsInDaHouse[] = $person;

        If(count($WhoIsInDaHouse) == 2){ // someone is entering alone
            $Alone[$j]["start"] = $Time;
            $Alone[$j]["who"] = $person;
        }elseif(count($WhoIsInDaHouse)>2 && $prevcount == 2){ // not alone anymore
            $Alone[$j]["end"] = $Time;
            $Alone[$j]["duration"] = strtotime($Alone[$j]["end"])-strtotime($Alone[$j]["start"]);
            $j++;
        }
    }
    $prevcount = count($WhoIsInDaHouse);
}
Var_dump($Alone);

看美女跑https://3v4l.org/dCL2H

我花了很长时间才弄清楚我需要一个假人。谁知道假人会有用?

【讨论】:

  • 通过您的解决方案,我是否可以找出哪些员工在轮班时单独工作,而不是只检查单独的时间?
  • @Basit 所以你需要员工编号吗?
  • 是的,在轮班中独自工作的人,他独自工作的时间。 Andreas worked 4 min alone - Basit worked 10 min alone 像这样......我猜是由员工分组。
  • @Basit 试试更新的代码。
  • 如果 3 个人在一天中的不同时间单独工作,这段代码不会崩溃吗?
【解决方案2】:

一种方法是创建一个事件列表

Staff   Event Time
1       S     11:05
1       E     20:00
2       S     11:00
2       E     17:00 etc.

然后按时间顺序对它们进行排序并遍历事件。

如果一个人开始轮班,则将一个人添加到 staffOnShift 变量,如果是结束则减一。

如果 staffOnShift == 1 && 事件是轮班开始,则将自上次事件以来的分钟数添加到 minutesAlone 变量中。

希望这可以帮助您入门。

补充说明

是的,开始和结束需要被视为单独的事件,所以在排序后你会有一个类似的列表

Staff   S/E   Time       staffOnShift       minutesAlone
2        S    11:00           1               0
1        S    11:05           2               5
4        S    13:00           3               5
2        E    17:00           2               5
3        S    19:00           3               5
5        S    19:00           4               5
1        E    20:00           3               5
4        E    20:00           2               5
3        E    03:00           1               5
5        E    03:00           0               5 + 0 = 5

遍历此列表并在某人开始轮班时添加并在某人轮班结束时减去,这将为您提供每个事件的轮班人数,我已将其放在第 4 列中。

如果 staffOnShift == 1(在加法或减法之前),则将自上次事件以来的分钟数添加到 minutesAlone 变量中。 (这不是我上面所说的,但逻辑表有助于澄清)

对于您的数据,满足这些条件的唯一事件是第二个也是最后一个。所以会增加 5 分钟,因为开始时有 1 人轮班。最后也满足了条件,但由于最后两个事件之间没有分钟,因此不会添加到总数中。

【讨论】:

  • 抱歉,还不是很清楚。您已在单独的行中添加了开始结束时间并用se 标记它们。如果 shift 开始,则开始添加,直到结束?
  • 有一件事是,我需要找出当天单独工作的员工。我在想如何区分哪些员工一整天都在单独工作
  • 员工编号在第 1 列的数据中,因此您可以知道谁单独工作
  • 是的,第一列有员工ID
猜你喜欢
  • 1970-01-01
  • 2010-11-23
  • 2014-01-08
  • 2013-07-26
  • 2021-11-15
  • 2019-05-20
  • 2010-10-07
  • 2011-04-24
  • 1970-01-01
相关资源
最近更新 更多