[英]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.