Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/laravel/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 从今天开始循环,从一组模板生成轮班/轮班表列表_Php_Laravel - Fatal编程技术网

Php 从今天开始循环,从一组模板生成轮班/轮班表列表

Php 从今天开始循环,从一组模板生成轮班/轮班表列表,php,laravel,Php,Laravel,我有一组工作时间,并希望生成一个建议轮班的列表,所有这些都基于当前的“现在”时间,并向后工作到过去 例如,工时模板: $templateShifts=collect([ (对象)[ “id”=>1, “from_day”=>1,//mon “from_time”=>“09:00:00”, “直到日”=>1, “直到时间”=>“12:00:00”, ], (对象)[ “id”=>2, “from_day”=>1,//mon “from_time”=>“13:00:00”, “直到日”=>1, “直

我有一组工作时间,并希望生成一个建议轮班的列表,所有这些都基于当前的“现在”时间,并向后工作到过去

例如,工时模板:

$templateShifts=collect([
(对象)[
“id”=>1,
“from_day”=>1,//mon
“from_time”=>“09:00:00”,
“直到日”=>1,
“直到时间”=>“12:00:00”,
],
(对象)[
“id”=>2,
“from_day”=>1,//mon
“from_time”=>“13:00:00”,
“直到日”=>1,
“直到时间”=>“17:00:00”,
],
(对象)[
“id”=>3,
“from_day”=>2,//星期二
“from_time”=>“09:00:00”,
“直到第二天”=>2,
“直到时间”=>“17:00:00”,
],
(对象)[
“id”=>4,
“from_day”=>4,//周四
“from_time”=>“09:00:00”,
“直到第二天”=>4,
“直到时间”=>“17:00:00”,
],
(对象)[
“id”=>5,
“from_day”=>5,//fri
“from_time”=>“09:00:00”,
“直到日”=>5,
“直到时间”=>“17:00:00”,
]
]);
如果今天是星期四(1月4日),则应按相反顺序列出日期:

  • 星期四09:00-17:00(1月4日)
  • 星期二09:00-17:00(1月2日)
  • 周一13:00-17:00(1月1日)
  • 周一09:00-12:00(1月1日)
  • 星期五09:00-17:00(12月31日)
  • 星期四09:00-17:00(12月30日)
这段代码感觉很糟糕,但我找不到一种方法,可以在收集循环结束时重复它,而不复制代码

//分页
$total_count=1000;
$on_page=30;
$page=$request->get('page')?:1;
$skip=$on_page*($page-1);
//从现在开始查找过去最接近的匹配项
$date=now();
$year=$date->year;
$weekNo=$date->weekOfYear;
$shifts=collect();
//减量第二周
如果($skip){
$weekNo-=$skip;
//将年份更改为正值周末
而($weekNo<1){
--美元/年;
$date->subYear();
$weekNo+=$date->isoweekssinyear;
}
}
//首页
如果(!$skip){
//今天第一次搜索shift
$firstShiftIndex=$TemplateShift->搜索(函数($item,$key)使用($date){
返回$item->from_day==$date->format('N')&&$item->from_time format('H:i:s');
});
$currentWeekNo=false;
if($firstShiftIndex==false){
//从今天开始循环,直到找到匹配的一天
对于($i=1;$i clone()->子天(1);
$firstShiftIndex=$TemplateShift->搜索(函数($item,$key)使用($date){
返回$item->from_day==$date->格式('N');
});
if($firstShiftIndex!==false){
$year=$date->year;
$weekNo=$date->weekOfYear;
打破
}
}
}
$templateShifts->slice($firstShiftIndex)->每个(函数($item,$key)使用($shifts,$date,$year,$weekNo){
$shift\u from=$date->clone()->setISODate($year,$weekNo,$item->from\u day);
列表($hour,$minutes)=分解(“:”,$item->from_time);
$shift\u from->setTime($hour,$minutes);
//进入下周/也可能是一年
如果($item->until_day<$item->from_day){
$weekNo++;
如果($weekNo<1){
--美元/年;
$date->subYear();
$weekNo=$date->isoWeeksInYear;
}
}
$shift\u till=$date->clone()->setISODate($year,$weekNo,$item->till\u day);
列表($hour,$minutes)=分解(“:”,$item->until_time);
$shift_until->setTime($hour,$minutes);
如果($shift\U from->toDateString()==$shift\U TILL->toDateString()){
$name=$shift\u from->format('d/m/Y d H:i').-'.$shift\u until->format('H:i');
}否则{
$name=$shift\u from->format('d/m/Y d H:i').-'.$shift\u直到->format('d H:i');
}
$shifts->push([
'id'=>$item->id,
'text'=>$name
]);
});
}
//
对于($i=0;$i<$on_第页;$i++){
--$weekNo;
如果($weekNo<1){
--美元/年;
$date->subYear();
$weekNo=$date->isoWeeksInYear;
}
$templateShifts->each(函数($item,$key)使用($shifts,$date,$year,$weekNo){
$shift\u from=$date->clone()->setISODate($year,$weekNo,$item->from\u day);
列表($hour,$minutes)=分解(“:”,$item->from_time);
$shift\u from->setTime($hour,$minutes);
//进入下周/也可能是一年
如果($item->until_day<$item->from_day){
$weekNo++;
如果($weekNo<1){
--美元/年;
$date->subYear();
$weekNo=$date->isoWeeksInYear;
}
}
$shift\u till=$date->clone()->setISODate($year,$weekNo,$item->till\u day);
列表($hour,$minutes)=分解(“:”,$item->until_time);
$shift_until->setTime($hour,$minutes);
如果($shift\U from->toDateString()==$shift\U TILL->toDateString()){
$name=$shift\u from->format('d/m/Y d H:i').-'.$shift\u until->format('H:i');
}否则{
$name=$shift\u from->format('d/m/Y d H:i').-'.$shift\u直到->format('d H:i');
}
$shifts->push([
'id'=>$item->id,
'text'=>$name
]);
});
}

首先,您预期的数据似乎是错误的,因为1月4日不是星期四(实际上是我的生日,那是星期一)

这是一个棘手的问题,因为有很多问题需要解决,我将把它分为3个阶段

  • 循环数周,而不是数天或轮班
  • 将轮班数据映射到给定的工作日
  • 计算距离,以查找最接近终点的偏移 本周我们正在循环
第一部分,我的想法是每周循环一次,计算出班次,减去我们迭代到下周的日期
$now = Carbon::parse('2021-01-04')->endOfDay();
$suggestions = collect();

while ($suggestions->count() <= 30) {
    $suggestedShifts = $this->suggestShifts($now);

    $suggestions->push(... $suggestedShifts);

    $now->subWeek()->endOfWeek(Carbon::SUNDAY);
}
private function suggestShifts(Carbon $date)
{
    return $this->shifts->map(function ($shift) use ($date) {
        if ($shift->until_day > $date->dayOfWeekIso) {
            return null;
        }

        $untilTime = explode(':', $shift->until_time);
        $shift->date = $date->clone()->subDays($date->dayOfWeekIso - $shift->until_day)->setTime($untilTime[0], $untilTime[1], $untilTime[2]);
        $shift->diff = $date->diff($shift->date)->h;

        return clone $shift;
    })->filter()
        ->sortByDesc(function ($shift) {
            return $shift->date->timestamp;
        })->all();
}
$suggestions->each(function ($shift) {
    $this->info('Shift: ');
    $this->info('starting - ' . $shift->date->clone()->setHour(explode(':', $shift->from_time)[0])->toIso8601ZuluString());
    $this->info('ending - ' . $shift->date->toIso8601ZuluString());
});

Shift:
starting - 2021-01-04T13:00:00Z
ending - 2021-01-04T17:00:00Z
Shift:
starting - 2021-01-04T09:00:00Z
ending - 2021-01-04T12:00:00Z
Shift:
starting - 2021-01-01T09:00:00Z
ending - 2021-01-01T17:00:00Z
Shift:
starting - 2020-12-31T09:00:00Z
ending - 2020-12-31T17:00:00Z
Shift:
starting - 2020-12-29T09:00:00Z
ending - 2020-12-29T17:00:00Z
Shift:
starting - 2020-12-28T13:00:00Z
ending - 2020-12-28T17:00:00Z
Shift:
starting - 2020-12-28T09:00:00Z
ending - 2020-12-28T12:00:00Z
Shift:
starting - 2020-12-25T09:00:00Z
ending - 2020-12-25T17:00:00Z
Shift:
starting - 2020-12-24T09:00:00Z
ending - 2020-12-24T17:00:00Z
Shift:
starting - 2020-12-22T09:00:00Z
ending - 2020-12-22T17:00:00Z
Shift:
starting - 2020-12-21T13:00:00Z
ending - 2020-12-21T17:00:00Z
Shift:
starting - 2020-12-21T09:00:00Z
ending - 2020-12-21T12:00:00Z
Shift:
starting - 2020-12-18T09:00:00Z
ending - 2020-12-18T17:00:00Z
Shift:
starting - 2020-12-17T09:00:00Z
ending - 2020-12-17T17:00:00Z
Shift:
starting - 2020-12-15T09:00:00Z
ending - 2020-12-15T17:00:00Z
Shift:
starting - 2020-12-14T13:00:00Z
ending - 2020-12-14T17:00:00Z
Shift:
starting - 2020-12-14T09:00:00Z
ending - 2020-12-14T12:00:00Z
Shift:
starting - 2020-12-11T09:00:00Z
ending - 2020-12-11T17:00:00Z
Shift:
starting - 2020-12-10T09:00:00Z
ending - 2020-12-10T17:00:00Z
Shift:
starting - 2020-12-08T09:00:00Z
ending - 2020-12-08T17:00:00Z
Shift:
starting - 2020-12-07T13:00:00Z
ending - 2020-12-07T17:00:00Z
Shift:
starting - 2020-12-07T09:00:00Z
ending - 2020-12-07T12:00:00Z
Shift:
starting - 2020-12-04T09:00:00Z
ending - 2020-12-04T17:00:00Z
Shift:
starting - 2020-12-03T09:00:00Z
ending - 2020-12-03T17:00:00Z
Shift:
starting - 2020-12-01T09:00:00Z
ending - 2020-12-01T17:00:00Z
Shift:
starting - 2020-11-30T13:00:00Z
ending - 2020-11-30T17:00:00Z
Shift:
starting - 2020-11-30T09:00:00Z
ending - 2020-11-30T12:00:00Z
Shift:
starting - 2020-11-27T09:00:00Z
ending - 2020-11-27T17:00:00Z
Shift:
starting - 2020-11-26T09:00:00Z
ending - 2020-11-26T17:00:00Z
Shift:
starting - 2020-11-24T09:00:00Z
ending - 2020-11-24T17:00:00Z
Shift:
starting - 2020-11-23T13:00:00Z
ending - 2020-11-23T17:00:00Z
Shift:
starting - 2020-11-23T09:00:00Z
ending - 2020-11-23T12:00:00Z
for ($i = 0; $i < count($array); $i++) {
    echo $array[$i]['id'];
    echo $array[$i]['from_day'];
    ...
}
for ($i = 0; $i < asYouLike; $i++) {
    
    $j = $i % count($array);           // this is the trick
    
    echo $array[$j]['id'];             //note use j for index
    echo $array[$j]['from_day'];       // j for index
    ...
}