5

我有一个复杂的任务,我已经把头撞到墙上好几天了。我尝试了大约 4 种不同的方法,但是每种方法似乎都停滞不前,而且变得非常令人沮丧。

我有一个时间范围。例如,14:30:00 到 18:30:00。考虑这个时间范围某人的工作班次。在此时间范围内,他们声明他们不能从 15:30:00 到 16:30:00 以及从 17:30:00 到 18:30:00 工作。我需要修改原始班次的开始和结束时间以删除冲突的班次。

原始移位数组如下所示:

$original_shift[0]['start'] = '14:30:00';
$original_shift[0]['end']   = '18:30:00';

从原始班次中删除的时间范围如下所示:

$subshift[0]['start'] = '15:30:00';
$subshift[0]['end']   = '16:30:00';
$subshift[1]['start'] = '17:30:00';
$subshift[1]['end']   = '18:30:00';

这是一个可视化:

在此处输入图像描述

所以,当我完成后,我基本上需要我原来的班次看起来像这样:

$original_shift[0]['start'] = '14:30:00';
$original_shift[0]['end']   = '15:30:00';
$original_shift[1]['start'] = '16:30:00';
$original_shift[1]['end']   = '17:30:00';

我还需要考虑的一些并发症是:

  1. 这些时间范围可以是任何时间(不限于我在示例中使用的半小时),但是我会 100% 确定不可用的时间范围将始终在原始班次的开始和之间开始和结束结束时间。

  2. 不可用时间可能会增加和/或占用整个原始班次的时间。

我不是在寻找一个“编写我的代码”的人,而是在寻找过去处理过类似事情并且可能对他们如何完成它有一些见解的人。

4

3 回答 3

3

当您特别要求“一些见解”而不是完整的工作答案时,我个人会选择填充“分钟”的数组。

$shift = array(
    'start' => '15:30:00',
    'end' => '18:30:00',

    'original' => array(),
    'unavailable' => array(),
    'modified' => array()
);

然后你会做一些棘手的扑克来转换15:30:00成 930 和18:30:001110(分钟数),这会给你开始时间和结束时间之间的差异。

用于range()快速填充original数组,以类似的格式加载您的数组,unavailable然后使用array_intersect()array_diff()计算原始班次中的哪些分钟不可用。

从那里,建立modified数组,并直接从那里读取到您的输出。

于 2012-10-29T21:20:28.790 回答
3

您需要计算时间范围。如图所示,这似乎是一个简单的减法。拥有执行这些操作的对象会很好。

我没有为此准备好的代码,因此以下概念有点粗糙,尽管可能还不错。

Range表示时间从到到的类型。这些都是为了DateTime可以利用这些现有类型的好处。到目前为止,我并没有使用太多的好处,但是对于应用程序的其余部分,这可能是有意义的。

Range类型已经包含一些我认为对进行部分计算有用的基本比较方法。

然而,由于一个对象不能将自己一分为二,我还创建了一个Ranges可以表示一个或多个Ranges 的类型。这对于有一些可以“划分”的东西是必要的。

我在这里作弊了一点,因为我将差异计算实现为 的成员,返回一个包含一个或多个对象Range的数组。Range然后,最终的计算只是进行一次移位并从中减去不可用的范围:

$shift = new Ranges(new DateTime('14:30:00'), new DateTime('18:30:00'));

$unavailables = new Ranges([
    new Range(new DateTime('15:30:00'), new DateTime('16:30:00')),
    new Range(new DateTime('17:30:00'), new DateTime('18:30:00')),
]);

$shift->subtract($unavailables);

然后转变跨越:

14:30:00 - 15:30:00
16:30:00 - 17:30:00

演示要旨

我不能说它是否值得抽象,DateTime对象的好处在于您可以将它们与>,<=. 当您需要在 Range 和 Ranges 之间进行更多计算时,这些类的真正好处可能会显现出来。也许界面还不够甜美,但是代码中已经概述了背后的基本计算。

14:00-15:00一个警告:我的代码中和之间的差异14:00-15:00将导致14:00-14:00. 我保持开始时间不会空着,但你也可以空着。Ranges 对象应该可以很好地处理它。

于 2012-10-30T00:57:50.970 回答
1

代码应该不言自明:

$original_shift[0]['start'] = '14:30:00';
$original_shift[0]['end'] = '18:30:00';

$breaks[0]['start'] = '14:30:00';
$breaks[0]['end'] = '15:30:00';
$breaks[1]['start'] = '16:30:00';
$breaks[1]['end'] = '17:30:00';

$modified_shift = array(
    array('start' => $original_shift[0]['start'])
);

for($x = 0, $y = count($breaks), $z = 0; $x < $y; $x++){
    $modified_shift[$z]['end'] = $breaks[$x]['start'];
    if($modified_shift[$z]['end'] != $modified_shift[$z]['start']){
        $z++;       
    }
    $modified_shift[$z]['start'] = $breaks[$x]['end'];
}

$modified_shift[$z]['end'] = $original_shift[0]['end'];

if($modified_shift[$z]['end'] == $modified_shift[$z]['start']){
    unset($modified_shift[$z]);
}
于 2012-10-29T21:34:56.100 回答