我目前正在开展一个项目并遇到一个我目前无法解决的挑战。我已经尝试了很长时间,并且最终将我的场景放在这里,因为我可以得到一些有用的提示。另外,请耐心等待,因为我将详细介绍这个问题。
所以,我有一个项目,其中包含根据班次时间(时间为24小时格式)计算员工工资的模块。现在,工资率根据工作时间(周一至周五)的时间而有所不同,工资率分为两部分:Week Day
和Week 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小时。因此,从0000
到0600
(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。
请高度赞赏这方面的任何帮助。 感谢。
答案 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;
}