laravel - Laravel - 如何从休假请求中提取假期和周末
问题描述
我正在使用 Laravel-5.8 开发员工休假平台。
目前,我正在申请休假。每年年初,管理员设置所有假期并存储在 hr_holiday_dates 表中,如下所示:
class HrHolidayDate extends Model
{
protected $table = 'hr_holiday_dates';
protected $primaryKey = 'id';
protected $fillable = [
'holiday_name',
'date_from',
'date_to',
];
}
员工登录应用程序提出请假请求。
型号:HrLeaveRequest:
class HrLeaveRequest extends Model
{
public $timestamps = false;
protected $table = 'hr_leave_requests';
protected $primaryKey = 'id';
protected $fillable = [
'id',
'employee_id',
'reason',
'leave_type_id',
'commencement_date',
'resumption_date',
'no_of_days',
];
public function employee()
{
return $this->belongsTo('App\Models\Hr\HrEmployee','employee_id');
}
public function leaveType()
{
return $this->belongsTo('App\Models\Hr\HrLeaveType','leave_type_id');
}
}
当员工提出请假时,他选择leave_type、beginning_date和resumption_date。no_of_days 未选择,而是基于应用程序智能。
控制器
public function create()
{
return view('hr.leave_requests.create');
}
public function store(StoreLeaveRequest $request)
{
try {
$commencementDate = Carbon::parse($request->commencement_date);
$resumptionDate = Carbon::parse($request->resumption_date);
$employeeId = Auth::user()->employee_id;
$leave = new HrLeaveRequest();
$leave->leave_type_id = $request->leave_type_id;
$leave->commencement_date = $commencementDate ->toDateTimeString();
$leave->resumption_date = resumptionDate ->toDateTimeString();
$leave->no_of_days = $request->no_of_days;
Session::flash('success', 'Leave Request is created successfully');
return redirect()->route('hr.leave_requests.index');
} catch (Exception $exception) {
Session::flash('error', 'Action failed! Please try again');
return redirect()->route('hr.leave_requests.index');
}
}
对于休假 no_of_days,我想要的是这个,应用程序在开始日期和恢复日期之间得到它。但在此之前,它会从选定日期中删除周末(周六和周日)。此外,它会进入所选日期范围内的 hr_holiday_days 并提取假期。它还应该考虑到假期中的周末。
如何得到:
$leave->no_of_days
从上面的解释?
谢谢你。
解决方案
Enter the starting and ending dates, along with an array of any holidays that might be in between, and it returns the working days as an integer:
<?php
//The function returns the no. of business days between two dates and it skips the holidays
function getWorkingDays($startDate,$endDate,$holidays){
// do strtotime calculations just once
$endDate = strtotime($endDate);
$startDate = strtotime($startDate);
//The total number of days between the two dates. We compute the no. of seconds and divide it to 60*60*24
//We add one to inlude both dates in the interval.
$days = ($endDate - $startDate) / 86400 + 1;
$no_full_weeks = floor($days / 7);
$no_remaining_days = fmod($days, 7);
//It will return 1 if it's Monday,.. ,7 for Sunday
$the_first_day_of_week = date("N", $startDate);
$the_last_day_of_week = date("N", $endDate);
//---->The two can be equal in leap years when february has 29 days, the equal sign is added here
//In the first case the whole interval is within a week, in the second case the interval falls in two weeks.
if ($the_first_day_of_week <= $the_last_day_of_week) {
if ($the_first_day_of_week <= 6 && 6 <= $the_last_day_of_week) $no_remaining_days--;
if ($the_first_day_of_week <= 7 && 7 <= $the_last_day_of_week) $no_remaining_days--;
}
else {
// (edit by Tokes to fix an edge case where the start day was a Sunday
// and the end day was NOT a Saturday)
// the day of the week for start is later than the day of the week for end
if ($the_first_day_of_week == 7) {
// if the start date is a Sunday, then we definitely subtract 1 day
$no_remaining_days--;
if ($the_last_day_of_week == 6) {
// if the end date is a Saturday, then we subtract another day
$no_remaining_days--;
}
}
else {
// the start date was a Saturday (or earlier), and the end date was (Mon..Fri)
// so we skip an entire weekend and subtract 2 days
$no_remaining_days -= 2;
}
}
//The no. of business days is: (number of weeks between the two dates) * (5 working days) + the remainder
//---->february in none leap years gave a remainder of 0 but still calculated weekends between first and last day, this is one way to fix it
$workingDays = $no_full_weeks * 5;
if ($no_remaining_days > 0 )
{
$workingDays += $no_remaining_days;
}
//We subtract the holidays
foreach($holidays as $holiday){
$time_stamp=strtotime($holiday);
//If the holiday doesn't fall in weekend
if ($startDate <= $time_stamp && $time_stamp <= $endDate && date("N",$time_stamp) != 6 && date("N",$time_stamp) != 7)
$workingDays--;
}
return $workingDays;
}
//Example:
$holidays=array("2008-12-25","2008-12-26","2009-01-01");
echo getWorkingDays("2008-12-22","2009-01-02",$holidays)
// => will return 7
?>
Referenced from : https://stackoverflow.com/a/336175/10309265
推荐阅读
- android - Android 中的消息应用程序无需用户交互即可触发 GET 链接
- machine-learning - k折交叉验证中较大或较小k的权衡
- c++ - CMake:“导入的目标
包括不存在的路径” - reactjs - Office Fluent UI / DatePicker - onSelectDate 不发送事件作为参数
- javascript - 从数据中删除叶节点
- javascript - 添加chart.js后,我的锚标签在我的网站中不起作用
- android - 云数据库 AGConnectInitializeProvider 错误
- node.js - Facebook API,创建创意错误无法加载帖子
- c# - 在 C# 中查找给定的 2 个字符串数组中的位置和差异项
- c++ - 如果功能已经启动,我该如何停止?