簡體   English   中英

從php中的序列化日期查找連續的時間段

[英]Find continuous time periods from serialized dates in 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-02-22至2017-02-23

2017年4月3日至2017年4月6日。

謝謝你的幫助!

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

我已經修改了$dates數組中的示例數據,以表明它可以容納月份更改和獨立日期。

以下所有方法均假定日期已按升序排序。 如果不是,則sort()將在Ymd格式的日期上工作; 否則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循環( 演示

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:嵌套While循環( 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循環( 演示

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',
  ),
)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM