Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.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_Date - Fatal编程技术网

Php 检查集合内的连续日期并返回为范围

Php 检查集合内的连续日期并返回为范围,php,date,Php,Date,我有一个Y-m-d格式的日期数组,可以是十个相隔一天的固定日期的任意组合 e、 g.这是全套: 2011-01-01、2011-01-02、2011-01-03、2011-01-04、2011-01-05、2011-01-06、2011-01-07、2011-01-08、2011-01-09、2011-01-10 从该集合创建的数组可以是日期的任意组合—所有日期、其中一个日期、一些连续日期、所有连续日期等等 我现在已经把它们打印出来了。e、 g.以下是一个可能的结果: 2011-01-02 20

我有一个Y-m-d格式的日期数组,可以是十个相隔一天的固定日期的任意组合

e、 g.这是全套:

2011-01-01、2011-01-02、2011-01-03、2011-01-04、2011-01-05、2011-01-06、2011-01-07、2011-01-08、2011-01-09、2011-01-10

从该集合创建的数组可以是日期的任意组合—所有日期、其中一个日期、一些连续日期、所有连续日期等等

我现在已经把它们打印出来了。e、 g.以下是一个可能的结果:

2011-01-02

2011-01-03

2011-01-04

2011-01-08

(实际打印的内容更像是“1月2日,星期五…”,但我们将使用简单的日期字符串)

我想压缩它,这样如果连续有三天或更多天,这些天就会变成一个范围,例如上面的例子会变成:

2011-01-02至2011-01-04

2011-01-08

最终会变成:

1月2日星期日-1月4日星期二

1月8日星期六


有没有办法循环检查时差,为范围创建开始时间和结束时间,然后收集掉队者?

这是一个快速回答,很抱歉没有实现,但假设您使用的是5.3,并且日期按时间顺序排列,您可以将每个日期转换为
DateTime
对象(如果尚未转换),然后使用生成
DateInterval
对象来迭代数组,您可以使用该对象将迭代中的当前日期与上一个日期进行比较。您可以将连续日期分组到子数组中,并使用
shift()
pop()
获取该子数组中的第一天和最后一天

编辑

我想了一下。下面是一个相当粗略和现成的实现,但它应该可以工作:

// assuming a chronologically
// ordered array of DateTime objects 

$dates = array(
    new DateTime('2010-12-30'), 
    new DateTime('2011-01-01'), 
    new DateTime('2011-01-02'), 
    new DateTime('2011-01-03'), 
    new DateTime('2011-01-06'), 
    new DateTime('2011-01-07'), 
    new DateTime('2011-01-10'),
);

// process the array

$lastDate = null;
$ranges = array();
$currentRange = array();

foreach ($dates as $date) {    

    if (null === $lastDate) {
        $currentRange[] = $date;
    } else {

        // get the DateInterval object
        $interval = $date->diff($lastDate);

        // DateInterval has properties for 
        // days, weeks. months etc. You should 
        // implement some more robust conditions here to 
        // make sure all you're not getting false matches
        // for diffs like a month and a day, a year and 
        // a day and so on...

        if ($interval->days === 1) {
            // add this date to the current range
            $currentRange[] = $date;    
        } else {
            // store the old range and start anew
            $ranges[] = $currentRange;
            $currentRange = array($date);
        }
    }

    // end of iteration... 
    // this date is now the last date     
    $lastDate = $date;
}

// messy... 
$ranges[] = $currentRange;

// print dates

foreach ($ranges as $range) {

    // there'll always be one array element, so 
    // shift that off and create a string from the date object 
    $startDate = array_shift($range);
    $str = sprintf('%s', $startDate->format('D j M'));

    // if there are still elements in $range
    // then this is a range. pop off the last 
    // element, do the same as above and concatenate
    if (count($range)) {
        $endDate = array_pop($range);
        $str .= sprintf(' to %s', $endDate->format('D j M'));
    }

    echo "<p>$str</p>";
}

此问题中提供的所有日期都是连续的,您到底在寻找什么?可能的日期列表是连续的。返回的实际日期可以是该日期列表中的任意组合(参见我的“可能结果”示例)。谢谢!几周前,我已经升级到5.3版,专门针对所有新的漂亮DateTime功能。我会研究一下,试一下,然后再报告。@Darragh,你知道如何在一个范围内包含两次约会吗?我的设置是轮班制,有时一天有两班。因此,在我的日期数组中,一个日期可能出现两次,并且应该包含在一个日期范围中,但您的代码将标记为单独的一天。提前谢谢!Hi@maartenmachiels-我想最快的答案可能是将你的时间间隔比较基于小时,而不是(甚至除了)天。目前,代码只在天进行比较-如果($interval->days==1),请参阅行
if{//etc.
Thu 30 Dec
Sat 1 Jan to Mon 3 Jan
Thu 6 Jan to Fri 7 Jan
Mon 10 Jan