2017-02-24 67 views
0

我有以下陣列日期在PHP中:查找連載日期連續的時間段在PHP

Array ( 
    [0] => '2017-02-22' 
    [1] => '2017-02-23' 
    [2] => '2017-04-03' 
    [3] => '2017-04-04' 
    [4] => '2017-04-05' 
    [5] => '2017-04-06' 
) 

有沒有辦法找到包括陣列內期的持續時間?

例如,對於上述陣列預期的結果將是:

2017年2月22日2017年2月23日至

2017年4月3日至2017-04- 06。

感謝您的幫助!

+1

在條目上循環,並檢查前一條目是否是當前條目的前一天。 (您可能想要從這些數據字符串中創建DateTime對象,以便更容易檢查。)如果是,那麼您仍然有一個連續的時間段,如果不是,那麼您將處於新的開始時間。 – CBroe

+0

也許有趣(重複)? :[算法來組合/合併日期範圍](http://stackoverflow.com/questions/4972552/algorithm-to-combine-merge-date-ranges) –

回答

1

會有很多方法來執行這項任務。有些比其他人更難閱讀。我會列舉一些。我建議使用第一種方法來提高效率,也許可以使用第三種方法來簡化輸出修改。

我修改了$dates數組中的示例數據,以顯示它適應月份更改和獨立日期。

以下所有方法都將假定日期已按升序排列。如果沒有,那麼sort()將工作在Y-m-d格式化的日期;否則usort()將是必要的。

我的方法將日期的數組是這樣的:

$dates=[ 
    '2017-02-28', 
    '2017-03-01', 
    '2017-04-03', 
    '2017-04-04', 
    '2017-04-06', 
    '2017-04-08', 
    '2017-04-09', 
    '2017-04-10' 
]; 

和輸出這樣的:

array (
    0 => '2017-02-28 to 2017-03-01', 
    1 => '2017-04-03 to 2017-04-04', 
    2 => '2017-04-06 to 2017-04-06', 
    3 => '2017-04-08 to 2017-04-10', 
) 

方法1:單一的foreach循環(Demo

foreach($dates as $date){ 
    if(!isset($start_date)){ 
     $start_date=$date; // temporarily store new start date 
    }elseif($date==date("Y-m-d",strtotime("$start_date +1 day")) || (isset($end_date) && $date==date("Y-m-d",strtotime("$end_date +1 day")))){ 
     $end_date=$date; // temporarily store new or overwrite existing end date 
    }else{ 
     $result[]="$start_date to ".(!isset($end_date)?$start_date:$end_date); // current date is not in group, move temporary dates to result array 
     $start_date=$date; // overwrite previous start date 
     unset($end_date); // destroy previous end date 
    } 
} 
$result[]="$start_date to ".(!isset($end_date)?$start_date:$end_date); // move temporary dates to result array 
var_export($result); 

方法#2:循環嵌套(Demo

$copy=$dates; // make a copy in case $dates is to be used again later 
while($copy){ // iterate until the array is empty 
    while(!isset($range) || current($copy)==date("Y-m-d",strtotime(substr($range,-10)." +1 day"))){ // iterate while date is new or consecutive 
     $range=(!isset($range)?'':substr($range,0,10).' to ').array_shift($copy); // temporarily store/overwrite the range data 
    } 
    $result[]=(strlen($range)==10?"$range to $range":$range); // permanently store range data 
    unset($range); // destroy range string, for next iteration 
} 
var_export($result); 

方法#3:兩個foreach循環(Demo

foreach($dates as $date){ 
    if(!isset($grouped)){ // first group 
     $i=0; // first group, index is zero 
    }elseif($date!=date("Y-m-d",strtotime("$date_checker +1 day"))){ // if non-consecutive 
     ++$i; // next group, index is incremented 
    } 
    $grouped[$i][]=$date_checker=$date; // store date as temporary date checker and into appropriate group 
} 

foreach($grouped as $group){ 
    $result[]=current($group)." to ".end($group); 
} 
var_export($result); 

或者從在方法3的$grouped陣列,可以簡單地改變輸出結構,以包含「的範圍的字符串」與子陣列保持鍵各個日期爲要素使用該:

foreach($grouped as $group){ 
    $result[current($group)." to ".end($group)]=$group; 
} 

備選輸出:

array (
    '2017-02-28 to 2017-03-01' => 
    array (
    0 => '2017-02-28', 
    1 => '2017-03-01', 
), 
    '2017-04-03 to 2017-04-04' => 
    array (
    0 => '2017-04-03', 
    1 => '2017-04-04', 
), 
    '2017-04-06 to 2017-04-06' => 
    array (
    0 => '2017-04-06', 
), 
    '2017-04-08 to 2017-04-10' => 
    array (
    0 => '2017-04-08', 
    1 => '2017-04-09', 
    2 => '2017-04-10', 
), 
)