繁体   English   中英

PHP-将日期范围拆分为多个部分

[英]php - Split a date range into pieces

我需要将范围内的日期范围数组除以其他日期范围。

例如,我的起始数组可以是:

$items = array(
    array(
        'ID' => 2,
        'from' => new DateTime('2016-07-01'),
        'to' => new DateTime('2016-07-19')
    ),
    array(
        'ID' => 3,
        'from' => new DateTime('2016-07-15'),
        'to' => new DateTime('2016-07-29')
    ),
    array(
        'ID' => 1,
        'from' => new DateTime('2016-01-01'),
        'to' => new DateTime('2016-12-31')
    ),
    array(
        'ID' => 4,
        'from' => new DateTime('2016-06-15'),
        'to' => new DateTime('2016-07-07')
    ),
    array(
        'ID' => 5,
        'from' => new DateTime('2016-07-05'),
        'to' => new DateTime('2016-07-17')
    ),
);

而且我期望的结果是一个包含所有期间的数组,并引用了item的ID,如下所示:

$result = array(
    array(
        'from' => new DateTime('2016-01-01'),
        'to' => new DateTime('2016-06-14'),
        'ids' => array(
            1
        )
    ),
    array(
        'from' => new DateTime('2016-06-15'),
        'to' => new DateTime('2016-06-30'),
        'ids' => array(
            1, 4
        )
    ),
    array(
        'from' => new DateTime('2016-07-01'),
        'to' => new DateTime('2016-07-04'),
        'ids' => array(
            1, 2, 4
        )
    ),
    array(
        'from' => new DateTime('2016-07-05'),
        'to' => new DateTime('2016-07-07'),
        'ids' => array(
            1, 2, 4, 5
        )
    ),
    array(
        'from' => new DateTime('2016-07-08'),
        'to' => new DateTime('2016-07-14'),
        'ids' => array(
            1, 2, 5
        )
    ),
    array(
        'from' => new DateTime('2016-07-15'),
        'to' => new DateTime('2016-07-17'),
        'ids' => array(
            1, 2, 3, 5
        )
    ),
    array(
        'from' => new DateTime('2016-07-18'),
        'to' => new DateTime('2016-07-19'),
        'ids' => array(
            1, 2, 3
        )
    ),
    array(
        'from' => new DateTime('2016-07-20'),
        'to' => new DateTime('2016-07-29'),
        'ids' => array(
            1, 3
        )
    ),
    array(
        'from' => new DateTime('2016-07-30'),
        'to' => new DateTime('2016-12-31'),
        'ids' => array(
            1
        )
    ),
);

你能帮助我吗? 谢谢

更新现在我已经尝试按“ from”项和循环项以及范围数组对数组进行排序。 这是我的代码:

usort($items, function($a, $b) {
    if ($a['from'] == $b['from']) {
        return 0;
    }
    if ($a['from'] < $b['from']) {
        return -1;
    }
    return 1;
});

$ranges = array(
    array(
        'from' => clone $items[0]['from'],
        'to' => clone $items[0]['to'],
        'ids' => array($items[0]['ID'])
    )
);
unset($items[0]);
foreach($items as $item) {
    foreach($ranges as $k => $range) {
        if (($range['from'] <= $item['from']) || ($range['to'] > $item['to'])) {
            if ($range['from'] <= $item['from']) {
                $clone = $range;
                $clone['from'] = $item['from'];
                $clone['to'] = clone $item['to'];
                $clone['ids'][] = $item['ID'];

                $ranges[$k]['to'] = clone $item['from'];
                $ranges[$k]['to']->modify('-1 day');
                $ranges[] = $clone;
            }

            if ($range['to'] > $item['to']) {
                $clone = $range;
                $clone['from'] = clone $item['to'];
                $clone['from']->modify('+1 day');
                $clone['to'] = clone $range['to'];
                $ranges[] = $clone;
            }
        }
    }
}

但是结果是一个数组,需要更多结果。 谢谢您的帮助。

老实说,我会将其设置为一个多步骤的过程……尽管我确定可以一步完成,但是代码可能会(而且可能已经)令人困惑(因为我不理解您的代码)在几秒钟内):

我将从一遍开始,将所有to+1日期和所有from日期存储到一个数组中并对其进行排序。

现在您有了间隔。 第一项是from ,且必须与最小from日期。 下一个日期可以是to+1from日期。 无论哪种方式,间隔为from到无论下一个是减1的一个区间从该值开始直到,直到下一个-1等。

下一步,将原始间隔分类为新间隔。 (并过滤掉那些不包含任何内容的间隔。)

除非性能/存储是一个非常大的问题,否则这将足够好,并且无论您的代码将被继承的人如何理解。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM