根据不同的工资率格式计算工资

时间:2014-09-11 05:53:31

标签: php codeigniter datetime logic strtotime

我目前正在开展一个项目并遇到一个我目前无法解决的挑战。我已经尝试了很长时间,并且最终将我的场景放在这里,因为我可以得到一些有用的提示。另外,请耐心等待,因为我将详细介绍这个问题。

所以,我有一个项目,其中包含根据班次时间(时间为24小时格式)计算员工工资的模块。现在,工资率根据工作时间(周一至周五)的时间而有所不同,工资率分为两部分:Week DayWeek Night.此外,weekend(星期六和星期日)的工资率也与正常天数不同。最后,有public holidays,他们也有不同于其他事件的工资率。下表显示了工资率摘要:

------------------------------------------
|Event         | Shift Times              |
------------------------------------------
|Week Day      | 0600-1800                |
------------------------------------------
|Week Night    | 1800-0600                |
------------------------------------------
|Weekend       | All day weekend rate     |
-------------------------------------------
|Public holiday|All day public holiday rate|
-------------------------------------------+

现在,如果您只需要为该特定日期分配工资率,例如轮班是在公共假期然后分配公共假期费率,那么这看起来非常简单,但问题是我的项目不是这种情况。

工作原理

现在,这种转变通常为12小时,可以介于两种不同的工资率之间,例如,一位员工从0900开始,在2100完成Monday。因此,按week day付费率计算小时数为9小时,week night付费率为3小时。同样,员工可以采用三种不同的工资率进行转移,例如:班次从2200周日晚开始,到0900早晨结束Monday。因此,由于周日晚上的班次开始和2小时后的周末结束,付费率小时将是weekend费率的2小时。因此,从00000600(6小时),工资率将基于week night费率,其余时间则在工作日之下。

现在好消息是我能够做到现在为止。一切都很完美。虽然我已经把很多条件放在里面,我认为这不是一个好习惯但是暂时我想让它运行起来。 Public Holiday发生时会出现问题。现在,公共假期是最困难的部分,因为它可以在任何一天(工作日和周末)进行,并且必须在每种情况下重新检查,并且必须进行加工和减少时间太复杂且不起作用。如果整个班次属于公众假期,我能够做到这一点。但是,当它下降超过一个支付率类别时,我就很难解决问题。我不会分享公共假期的一个代码,因为代码太复杂而且你可能会感到困惑。但是,我将分享其他付费率格式工作正常的代码。

注意 我建议你不要从我的代码中得到任何想法,因为我想要你的建议,如果你查看我的代码,你可能会用尽想法。

function getHoursBreakDown($time1, $time2){

    $hoursForShift = array(
        "weekday" => 0,
        "weeknight" => 0,
        "saturday" => 0,
        "sunday" => 0,
        "public" => 0
    );

    $t1 = strtotime($time1);
    $t2 = strtotime($time2);

    $t1_Day = (int) date("N", $t1);
    $t2_Day = (int) date("N", $t2);

    $t1_Hour = (int) date("G", $t1);
    $t2_Hour = (int) date("G", $t2);

    $t1_Date = (int) date("j", $t1);
    $t2_Date = (int) date("j", $t2);

    $t1_Month = (int) date("n", $t1);
    $t2_Month = (int) date("n", $t2);

    $t1_Minutes = round(date("i", $t1) / 60, 2); // to substitute, extra
    $t2_Minutes = round(date("i", $t2) / 60, 2); // to add, lost

    // Working days
    if ($t1_Day<6) {


        if ($t1_Hour > $t2_Hour) $t2_Hour += 24;

        for($i = $t1_Hour; $i< $t2_Hour; $i++){


            if (($i>= 6 && $i < 18) || ($t2_Day < 6 && $i >= 30) ) {
                $hoursForShift['weekday']++;

            } else if ($t2_Day < 6 || $i < 24) {
                $hoursForShift['weeknight']++;

            } else if ($t2_Day == 6) {
                $hoursForShift['saturday']++;

            } else if ($t2_Day == 7) {
                $hoursForShift['sunday']++;
            }
        }

        $t2_Hour = ($t2_Hour > 23) ? $t2_Hour - 24: $t2_Hour;

        // Deducting extra minutes from sign in time
        if      ($t1_Hour >= 6 && $t1_Hour < 18) $hoursForShift['weekday']   -= $t1_Minutes;
        else if ($t1_Hour  < 6 || $t1_Hour >= 18) $hoursForShift['weeknight'] -= $t1_Minutes;

        // Adding lost minutes to sign out
        if      ($t2_Day < 6 && ($t2_Hour >= 6 && $t2_Hour < 18)){  $hoursForShift['weekday']   += $t2_Minutes; }
        else if ($t2_Day < 6 && ($t2_Hour  < 6 || $t2_Hour >= 18))  $hoursForShift['weeknight'] += $t2_Minutes;

        // Adding lost minutes to sign out if, sign out on weekend
        if      ($t2_Day == 6) $hoursForShift['saturday'] += $t2_Minutes;
        else if ($t2_Day == 7) $hoursForShift['sunday'] += $t2_Minutes;

    } else {
        //Weekends

        if ($t1_Hour > $t2_Hour) $t2_Hour += 24;

        for($i = $t1_Hour; $i< $t2_Hour; $i++){

            if ($t2_Day == 1 && ($i%24) < 12) {
                $hoursForShift['weeknight']++;

            } else if ($t1_Day == 6 && $i < 24) {
                $hoursForShift['saturday']++;

            } else if ($t1_Day == 7 || ($t1_Day == 6 && $i >= 24)) {
                $hoursForShift['sunday']++;
            }
        }

        if ($t2_Day == 1) $hoursForShift['weeknight'] -= $t1_Minutes;
        if ($t2_Day == 6) $hoursForShift['saturday'] -= $t1_Minutes;
        else if ($t2_Day == 7) $hoursForShift['sunday'] -= $t1_Minutes;

        if ($t2_Day == 1) $hoursForShift['weeknight'] += $t2_Minutes;
        else if ($t2_Day == 6) $hoursForShift['saturday'] += $t2_Minutes;
        else if ($t2_Day == 7) $hoursForShift['sunday']   += $t2_Minutes;
    }
}

好的是,数据库中没有任何东西出来。这个问题基于完全的思维计算和技术,并且开发了纯PHP。

请高度赞赏这方面的任何帮助。 感谢。

1 个答案:

答案 0 :(得分:3)

哈夫!!经过长时间的努力和整天拉扯我的头发,我终于能够找出问题的解决方案。以下功能是我正在寻找的问题的全部答案。

   function getHoursBreakDown($time1, $time2){

    $hoursForShift = array(
        "weekday" => 0,
        "weeknight" => 0,
        "saturday" => 0,
        "sunday" => 0,
        "public" => 0
    );

    $t1 = strtotime($time1);
    $t2 = strtotime($time2);

    $t1_Day = (int) date("N", $t1);
    $t2_Day = (int) date("N", $t2);

    $t1_Hour = (int) date("G", $t1);
    $t2_Hour = (int) date("G", $t2);

    $t1_Date = (int) date("j", $t1);
    $t2_Date = (int) date("j", $t2);

    $t1_Month = (int) date("n", $t1);
    $t2_Month = (int) date("n", $t2);

    $t1_Year = (int) date("Y", $t1);
    $t2_Year = (int) date("Y", $t2);

    $t1_Minutes = round(date("i", $t1) / 60, 2); // to substitute, extra
    $t2_Minutes = round(date("i", $t2) / 60, 2); // to add, lost

    $start=explode(' ', $time1);
    $finish=explode(' ', $time2);

       $publicHolidays = array(
        "2014-01-01",
        "2014-01-27",
        "2014-04-18",
        "2014-04-19",
        "2014-04-21",
        "2014-04-25",
        "2014-06-09",
        "2014-08-17",
        "2014-10-06",
        "2014-11-14",
        "2014-12-25",
        "2014-12-26"

    );


    // Working days
    if ($t1_Day<6 ) {

        if ($t1_Hour > $t2_Hour) $t2_Hour += 24;

        for($i = $t1_Hour; $i< $t2_Hour; $i++){


            if (($i>= 6 && $i < 18) || ($t2_Day < 6 && $i >= 30 && $i< 42) ) {
                $hoursForShift['weekday']++;

            } else if ($t2_Day < 6 || $i < 24) {
                $hoursForShift['weeknight']++;

            } else if ($t2_Day == 6) {
                $hoursForShift['saturday']++;

            } else if ($t2_Day == 7) {
                $hoursForShift['sunday']++;
            }
        }

        $t2_Hour = ($t2_Hour > 23) ? $t2_Hour - 24: $t2_Hour;

        // Deducting extra minutes from sign in time
        if((!in_array($start[0], $publicHolidays)) && (!in_array($finish[0], $publicHolidays))) {
        if      ($t1_Hour >= 6 && $t1_Hour < 18) $hoursForShift['weekday']   -= $t1_Minutes;
        else if ($t1_Hour  < 6 || $t1_Hour >= 18) $hoursForShift['weeknight'] -= $t1_Minutes;

        // Adding lost minutes to sign out
        if      ($t2_Day < 6 && ($t2_Hour >= 6 && $t2_Hour < 18)){  $hoursForShift['weekday']   += $t2_Minutes; }
        else if ($t2_Day < 6 && ($t2_Hour  < 6 || $t2_Hour >= 18))  $hoursForShift['weeknight'] += $t2_Minutes;

        // Adding lost minutes to sign out if, sign out on weekend
        if      ($t2_Day == 6) $hoursForShift['saturday'] += $t2_Minutes;
        else if ($t2_Day == 7) $hoursForShift['sunday'] += $t2_Minutes;
    }

    } else if($t1_Day>=6)  {
        //Weekends

        if ($t1_Hour > $t2_Hour) $t2_Hour += 24;

        for($i = $t1_Hour; $i< $t2_Hour; $i++){


            if ($t2_Day == 1 &&  $i>=24 && $i<30) {
                $hoursForShift['weeknight']++;

            }else if ($t2_Day == 1 && $i>29  && $i<42) {
                $hoursForShift['weekday']++;

            }else if ($t1_Day == 6 && $i < 24) {
                $hoursForShift['saturday']++;

            } else if ($t1_Day == 7 || ($t1_Day == 6 && $i >= 24)) {
                $hoursForShift['sunday']++;
            }
        }


        if((!in_array($start[0], $publicHolidays)) && (!in_array($finish[0], $publicHolidays))) {
        $t2_Hour = ($t2_Hour > 23) ? $t2_Hour - 24: $t2_Hour;

        if ($t1_Day == 1 && $t1_Hour>=0 && $t1_Hour<6 ) $hoursForShift['weeknight'] -= $t1_Minutes;
        else if ($t1_Day == 1 && $t1_Hour>=6 && $t1_Hour<18 ) $hoursForShift['weekday'] -= $t1_Minutes;
        else if ($t1_Day == 6) $hoursForShift['saturday'] -= $t1_Minutes;
        else if ($t1_Day == 7) $hoursForShift['sunday'] -= $t1_Minutes;

        if ($t2_Day == 1 && $t2_Hour<6 || $t2_Day == 1 && $t2_Hour>=18) $hoursForShift['weeknight'] += $t2_Minutes;
        else if ($t2_Day == 1 && $t2_Hour>=6 && $t2_Hour < 18) $hoursForShift['weekday'] += $t2_Minutes;
        else if ($t2_Day == 6 ) $hoursForShift['saturday'] += $t2_Minutes;
        else if ($t2_Day == 7) $hoursForShift['sunday']   += $t2_Minutes;
    }

    }
       // If the start and end date is public holiday
        if((in_array($start[0], $publicHolidays)) && (in_array($finish[0], $publicHolidays)))

        {

            $hoursForShift['public'] = $hoursForShift['weekday'];
            $hoursForShift['weekday'] = 0;

            $hoursForShift['public'] += $hoursForShift['weeknight'];
            $hoursForShift['weeknight'] = 0;

            $hoursForShift['public'] += $hoursForShift['saturday'];
            $hoursForShift['saturday'] = 0;

            $hoursForShift['public'] += $hoursForShift['sunday'];
            $hoursForShift['sunday'] = 0;

            $hoursForShift['public'] -= $t1_Minutes;
            $hoursForShift['public'] += $t2_Minutes;

           //If start date is on public holiday but the end date
        }else if ((in_array($start[0], $publicHolidays)) && (! in_array($finish[0], $publicHolidays))) {


           if ($t1_Hour > $t2_Hour) $t2_Hour += 24;


           for($i = $t1_Hour; $i<24; $i++){

            if($t1_Day<6){    


            if (($i>=6 && $i <18)) {
                $hoursForShift['weekday']--;
                $hoursForShift['public']++;

            } else if ($i >=18 && $i <24) {

                $hoursForShift['weeknight']--;
                $hoursForShift['public']++;

            }
            else if ($i>0 && $i<=6) {
                $hoursForShift['weeknight']--;
                $hoursForShift['public']++;
             } 
           } else if ($t1_Day == 6) {

                $hoursForShift['saturday']--;
                $hoursForShift['public']++;

            } else if ($t1_Day == 7) {

                $hoursForShift['sunday']--;
                $hoursForShift['public']++;
            }
        }

         $t2_Hour = ($t2_Hour > 23) ? $t2_Hour - 24: $t2_Hour;

         $hoursForShift['public'] -= $t1_Minutes;


        if ($t2_Day <6 && $t2_Hour>0 && $t2_Hour<6 || $t2_Day <6 && $t2_Hour>=18) $hoursForShift['weeknight'] += $t2_Minutes;
        else if ($t2_Day <6 && $t2_Hour>=6 && $t2_Hour < 18) $hoursForShift['weekday'] += $t2_Minutes;
        else if ($t2_Day == 6 ) $hoursForShift['saturday'] += $t2_Minutes;
        else if ($t2_Day == 7) $hoursForShift['sunday']   += $t2_Minutes;

        //If the start date is not on a public holiday but end date is.

        }else if ((! in_array($start[0], $publicHolidays)) && (in_array($finish[0], $publicHolidays))) {


           if ($t1_Hour > $t2_Hour) $t2_Hour += 24;


           for($i = 25; $i<= $t2_Hour; $i++){

            if($t2_Day<6){    

            if ( $i>24 && $i <=30 ) {
                $hoursForShift['weeknight']--;
                $hoursForShift['public']++;

            } else if ($i >=30 && $i < 42 ) {

                $hoursForShift['weekday']--;
                $hoursForShift['public']++;

            }

           } else if ($t2_Day == 6) {

                $hoursForShift['saturday']--;
                $hoursForShift['public']++;

            } else if ($t2_Day == 7) {

                $hoursForShift['sunday']--;
                $hoursForShift['public']++;
            }
        }


         $hoursForShift['public'] += $t2_Minutes;


        if ($t1_Day <6 && $t1_Hour>0 && $t1_Hour<6 || $t1_Day <6 && $t1_Hour>=18) $hoursForShift['weeknight'] -= $t1_Minutes;
        else if ($t1_Day <6 && $t1_Hour>=6 && $t1_Hour < 18) $hoursForShift['weekday'] -= $t1_Minutes;
        else if ($t1_Day == 6 ) $hoursForShift['saturday'] -= $t1_Minutes;
        else if ($t1_Day == 7) $hoursForShift['sunday']   -= $t1_Minutes;


        }


     return $hoursForShift;
    }