我嘗試了@ebelendez的代碼來計算兩個日期之間的作業時間,但是我對如何將星期六的值設定為 3 小時(08:00-11:00)感到困惑。例如,作業日每天的作業時間是 8 小時(不包括 1 小時的休息時間),假設我想得到從周四到周六的總作業時間,預期結果是 19 小時。
這是我所做的。有人可以幫我弄這個嗎?
$from = '2022-04-21 07:00:00';
$to = '2022-04-23 16:00:00';
echo abs(get_working_hours($from, $to));
function get_working_hours($from,$to){
//config
$ini_time = [7,0]; //hr, min
$end_time = [16,0]; //hr, min
//date objects
$ini = date_create($from);
$ini_wk = date_time_set(date_create($from),$ini_time[0],$ini_time[1]);
$end = date_create($to);
$end_wk = date_time_set(date_create($to),$end_time[0],$end_time[1]);
//days
$workdays_arr = get_workdays($ini,$end);
$workdays_count = count($workdays_arr);
$workday_seconds = (($end_time[0] * 60 $end_time[1]) - ($ini_time[0] * 60 $ini_time[1])) * 60 - 3600;
//get time difference
$ini_seconds = 0;
$end_seconds = 0;
if(in_array($ini->format('Y-m-d'),$workdays_arr)) $ini_seconds = $ini->format('U') - $ini_wk->format('U');
if(in_array($end->format('Y-m-d'),$workdays_arr)) $end_seconds = $end_wk->format('U') - $end->format('U');
$seconds_dif = $ini_seconds > 0 ? $ini_seconds : 0;
if($end_seconds > 0) $seconds_dif = $end_seconds;
//final calculations
$working_seconds = ($workdays_count * $workday_seconds) - $seconds_dif;
return $working_seconds / 3600; //return hrs
}
function get_workdays($ini,$end){
//config
$skipdays = [0]; //sunday:0
$skipdates = [];
//vars
$current = clone $ini;
$current_disp = $current->format('Y-m-d');
$end_disp = $end->format('Y-m-d');
$days_arr = [];
//days range
while($current_disp <= $end_disp){
if(!in_array($current->format('w'),$skipdays) && !in_array($current_disp,$skipdates)){
$days_arr[] = $current_disp;
}
$current->add(new DateInterval('P1D')); //adds one day
$current_disp = $current->format('Y-m-d');
}
return $days_arr;
}
uj5u.com熱心網友回復:
您的代碼和鏈接的答案似乎不必要地復雜。我們真正需要的是:
- 配置每天應該計算多少小時;
- 創建一個可迭代物件
DatePeriod(包含DateTime期間每個日期的物件); - 迭代日期,查找每天應該計算多少小時,總結一下。
class CountWorkingHours
{
// Define hours counted for each day:
public array $hours = [
'Mon' => 8,
'Tue' => 8,
'Wed' => 8,
'Thu' => 8,
'Fri' => 8,
'Sat' => 3,
'Sun' => 0
];
// Method for counting the hours:
public function get_hours_for_period(string $from, string $to): int
{
// Create DatePeriod with requested Start/End dates:
$period = new DatePeriod(
new DateTime($from),
new DateInterval('P1D'),
new DateTime($to)
);
$hours = [];
// Loop over DateTime objects in the DatePeriod:
foreach($period as $date) {
// Get name of day and add matching hours:
$day = $date->format('D');
$hours[] = $this->hours[$day];
}
// Return sum of hours:
return array_sum($hours);
}
}
用法(回傳給定時間段內的作業時間整數):
$cwh = new CountWorkingHours();
$hours = $cwh->get_hours_for_period('2022-04-21 07:00:00', '2022-04-30 16:00:00');
// = 62
如果您需要考慮標準每周小時數的公共假期等例外情況,您可以在“跳過日期”的周期回圈內添加一個檢查。例如,有一個$skip_dates包含非作業日陣列的屬性,然后!in_array($date->format('Y-m-d'), $this->skip_dates)在增加給定日期的作業時間之前檢查。
PS 此代碼假定您正在計算整個作業日。如果您的開始或結束時間是在作業日中間定義的,則不會考慮在內。(如果您想將其考慮在內,則必須配置日常作業時間,并且代碼必須在評估開始和結束日期時考慮到這一點。對于當前目的而言,這似乎是不必要的練習。)
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/464342.html
上一篇:檢查PandasDataFrame中兩列日期時間型別之間的重疊
下一篇:根據時間戳分隔行
