【问题标题】:Generate sheduler calendar from days in PHP从 PHP 中的天数生成调度程序日历
【发布时间】:2020-07-09 22:53:02
【问题描述】:

我正在尝试制作一个小程序来生成调度程序计划 所以,用户选择:

  • 一天或多天(例如:选择星期一、星期二和星期五)和每天的小时数
  • 输入starDate
  • 输入结束日期
  • 输入总小时数

之后生成sheduler计划

就我现在所拥有的而言,我被困在 foreach 中,因为它会为所有日子制定计划

function isTuesday($date) {
    return date('w', strtotime($date)) === '2';
}
function isWednesday($date) {
    return date('w', strtotime($date)) === '3';
}

    foreach(range(0,365) as $day) {
    $internal_date = date(INTERNAL_FORMAT, strtotime("{$start_date} + {$day} days"));
    $this_day = date(DISPLAY_DAY_FORMAT, strtotime($internal_date));
    $this_month = date(INTERNAL_FORMAT, strtotime($internal_date));
    if ((isTuesday($internal_date) || isWednesday($internal_date)) 
        && !isExcludedDate($internal_date)) {
            $months_and_dates[$this_month][] = $this_day;
    }
    
}

它生成从 A 到 B 日期的所有日期,每周二和周三 假设我使用 if 语句来检查是否选择了每周的每一天? 如果是星期一,只调用星期一函数 如果星期一和星期二,星期一和星期二函数 如果我遵循这个,我将有超过 30 个如果涵盖所有可能性,有什么办法可以缩短这个时间?

谢谢

更新 1

如果我使用 if,就在星期一我拥有所有这些

foreach(range(0,$datediff) as $day) {
    $internal_date = date(INTERNAL_FORMAT, strtotime("{$startDate} + {$day} days"));
    $this_day = date(DISPLAY_DAY_FORMAT, strtotime($internal_date));
    $this_month = date(INTERNAL_FORMAT, strtotime($internal_date));
    if($isSegunda != null ){
        if ((isSegunda($internal_date)) && !isExcludedDate($internal_date)) {
            $cronograma[$this_month][] = $this_day;
    }
    }
    if($isSegunda != null && $isTerca != null){
        if ((isSegunda($internal_date)) || isTerca($internal_date) && !isExcludedDate($internal_date)) {
            $cronograma[$this_month][] = $this_day;
    }
    }
    if($isSegunda != null && $isTerca != null && $isQuarta != null){
        if ((isSegunda($internal_date)) || isTerca($internal_date) || isQuarta($internal_date) && !isExcludedDate($internal_date)) {
            $cronograma[$this_month][] = $this_day;
    }
    }
    if($isSegunda != null && $isTerca != null && $isQuarta != null && $isQuinta != null){
        if ((isSegunda($internal_date)) || isTerca($internal_date) || isQuarta($internal_date) || isQuinta($internal_date) && !isExcludedDate($internal_date)) {
            $cronograma[$this_month][] = $this_day;
    }
    }
    if($isSegunda != null && $isTerca != null && $isQuarta != null && $isQuinta != null && $isSexta !=null){
        if ((isSegunda($internal_date)) || isTerca($internal_date) || isQuarta($internal_date) || isQuinta($internal_date) || isSexta($internal_date) && !isExcludedDate($internal_date)) {
            $cronograma[$this_month][] = $this_day;
    }
    }
    
    
    
}

【问题讨论】:

  • 如果我错了,请纠正我,您的代码应该:取 startDate、取 endDate、取工作日(例如周一、周二、周三、周四、周五、周六、周日)、totalHours(每天还是按计划?)。生成一个从开始到结束日期的计划计划,仅标记所选的工作日并满足总小时数要求,并以数组形式返回日历?
  • 确切地说,totalHours 是所有计划,而不是按天(例如,我可以有所有星期一 2 小时和星期五 3),检查我的更新
  • 应用程序是否应该在所有预定日期平均分配总小时数?
  • 是的,最好检查所有预定的日期,这样任何人都可以查看预定的日期 x , y 小时

标签: php


【解决方案1】:

好的,我创建了您的调度程序,而不是使用类更易读的方式

<?php

class Day
{
    private $free;
    private $workingHours;
    private $name;

    function __construct(string $name, bool $free, $workingHours = 0)
    {
        $this->name = $name;
        $this->free = $free;
        $this->workingHours = $workingHours;
    }

    public function setWorkingHours(int $workingHours)
    {
        $this->workingHours = $workingHours;
    }

    public function getWorkingHours(): int
    {
        return $this->workingHours;
    }

    public function isFree(): bool
    {
        return $this->free;
    }

    public function __toString()
    {
        return $this->name;
    }
}

class Scheduler
{
    const MONDAY = 'mon';
    const TUESDAY = 'tue';
    const WEDNESDAY = 'wed';
    const THURSDAY = 'thu';
    const FRIDAY = 'fri';
    const SATURDAY = 'sat';
    const SUNDAY = 'sun';

    public function createSchedule(\DateTime $startDate, \DateTime $endDate, int $totalHours, array $scheduledWeekDays): array
    {
        $schedule = [];
        $totalDays = 0;

        // Find all scheduled days
        while($startDate < $endDate) {
            $weekday = strtolower($startDate->format('D'));
            if ($this->isScheduledDay($weekday, $scheduledWeekDays)) {
                $schedule[] = new Day($weekday, false);
                $totalDays++;
            } else {
                $schedule[] = new Day($weekday, true);
            }
            $startDate->modify('+1days');
        }

        // Spread total hours evenly
        $hoursPerDay = floor($totalHours / $totalDays); // round it down
        $extraHours = $totalHours - ($hoursPerDay * $totalDays); // find the hours that were left by flooring

        $schedule = array_map(function(Day $day) use ($hoursPerDay) {
            if(!$day->isFree()) {
                $day->setWorkingHours($hoursPerDay);
            }

            return $day;
        }, $schedule);
        
        $lastDay = $schedule[count($schedule) - 1];
        $lastDay->setWorkingHours($lastDay->getWorkingHours() + $extraHours);

        return $schedule;
    }

    private function isScheduledDay(string $day, array $scheduledWeekDays)
    {
        return array_search($day, $scheduledWeekDays) !== false;
    }
}

$scheduler = new Scheduler();

$startDate = new \DateTime('tomorrow');
$endDate = (clone $startDate)->modify('+1week');

$schedule = $scheduler->createSchedule($startDate, $endDate, 16, [Scheduler::SATURDAY, Scheduler::SUNDAY]);

// 8 hours on saturday, and sunday
foreach($schedule as $day) {
    $text = 'Week day: ' . $day . '<br>';
    if($day->isFree()) {
        $text .= 'It\'s a free day enjoy ur time!';
    } else {
        $text .= 'Today you have to work ' . $day->getWorkingHours() . ' hours';
    }
    $text .= '<br><br>';

    echo $text;
}

例如,您可以扩展 day 类来表示这一天的确切日期。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-10
    • 1970-01-01
    • 2023-01-11
    相关资源
    最近更新 更多