【问题标题】:Work shift code bug in PHPPHP中的轮班代码错误
【发布时间】:2014-07-22 09:48:10
【问题描述】:

我对 php 代码有一个小问题,它可以找出员工在夜间工作了多少小时以及在白天工作了多少小时。

代码在这里:

function intersection($s1, $e1, $s2, $e2) {
    if ($e1 < $s2)
            return 0;
    if ($s1 > $e2)
            return 0;
    if ($s1 < $s2)
            $s1 = $s2;
    if ($e1 > $e2)
            $e1 = $e2;
    return $e1 - $s1;
}

    $start = strtotime("07:00");
    $end = strtotime("17:30");
    // $end = strtotime("05:30") + 3600*24; // the work ended at 05:30 morning of the next day

    $morning_start = strtotime("07:00");
    $morning_end = strtotime("15:00");

    $afternoon_start = strtotime("15:00");
    $afternoon_end = strtotime("23:00");

    $night_start = strtotime("23:00");
    $night_end = strtotime("07:00") + 3600*24; // 07:00 of next day, add 3600*24 seconds

    echo "morning: " . intersection( $start, $end, $morning_start, $morning_end ) / 3600 . " hours\n";
    echo "afternoon: " . intersection( $start, $end, $afternoon_start, $afternoon_end ) / 3600 . " hours\n";
    echo "night: " . intersection( $start, $end, $night_start, $night_end ) / 3600 . " hours\n";

我不是此代码的作者。版权属于用户 Javi R 和来自此问题的代码:Calculating shift hours worked。我做了这个,因为最初的问题大约有 3 年了,他们不再在那里回答了。

该 Javi R 代码几乎可以完美运行,但有一些我找不到的错误。

我的轮班时间更简单:22:00 -> 07:00 = 夜间工作,07:00 -> 22:00 = 白天工作。

我认为这些转变或其他东西的方式并不重要。我也尝试过使用原始代码,但仍然存在错误。

如果工作时间是 22:30 -> 08:00(结果:白天 = 0 小时,晚上 = 8:30 小时)和 20:00 -> 10:00(结果:白天 = 2 小时,夜晚 = 9 小时),但正确答案的工作时间为 23:00 -> 07:00(结果:白天 = 0 小时,夜晚 = 7 小时)。

正确的是:

22:30 -> 08:00 = 夜间 8.5 小时和白天 1 小时 20:00 -> 10:00 = 夜间 9 小时和白天 2 + 3 小时

我希望您能够解决我的问题和那个错误,以便代码能够完美运行并可以帮助其他有同样问题的人。

感谢您的帮助并感谢 Javi R 编写该代码。

【问题讨论】:

标签: php time clock strtotime shift


【解决方案1】:

当工作时间超过一个工作日时,就会出现问题。 就您的代码而言,一天从早上 7 点到早上 7 点(早上 7->15,下午 15->22,晚上​​ 22->7)。 如果一个人从下午 22 点工作到早上 8 点,那么一个人第一天工作 10 小时,第二天工作 1 小时。代码建议没有考虑这种溢出。

一个(远形式是完美的)修复可能是更改函数intersection(),如下所示:

function intersection($s1, $e1, $s2, $e2,$day) {

    return subintersection($s1,$e1,$s2,$e2)+subintersection($s1,$e1,$s2+$day,$e2+$day);
}

function subintersection($s1, $e1, $s2, $e2) {
    if ($e1 < $s2)
            return 0;
    if ($s1 > $e2)
            return 0;
    if ($s1 < $s2)
            $s1 = $s2;
    if ($e1 > $e2)
            $e1 = $e2;
    return $e1 - $s1;
}

并将您的电话改为intersection()。例如,早上:

$day=3600*24;
echo "morning: " . (intersection( $start, $end, $morning_start, $morning_end,$day))/3600 . " hours\n<br/>"

【讨论】:

  • 所以你的意思是它只处理 24 小时并且不接受其中的所有内容?例如,如果工作时间是从 17:00 PM 到 07:00 AM 可以,但是当工作时间是从 17:00 PM 到 07:01 AM 时,它不好吗?这样一分钟就溢出了,不会被接受?
  • 是的,你完全正确。我只是更新我的答案以提出修复建议。
  • $day 是什么?编辑:对不起,你已经回答了。我刚刚发现如果 $end 没有添加 +24,它只会显示零。它在那里的评论中。
  • 是的,当然,如果 $end$start 之前没有任何作用。如果 +$day$start 之前,可以添加一个测试以自动将 +$day 添加到 $end
  • 谢谢。有效。最后。欢迎使用其他解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-09
  • 1970-01-01
  • 1970-01-01
  • 2016-04-04
  • 2015-10-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多