php - 根据日期显示多维数组中的前3项

时间:2017-03-24 15:35:51

标签: php arrays date multidimensional-array

所以这就是我想要做的事情。我在多维数组中构建了一个位置和日期列表。我想根据日期和位置显示输出中接下来的3个即将到来的日期。此外,我需要在任何给定时刻仅显示每个位置的一个日期,所以基本上是距离位置1,2和3的最近日期,依此类推,并且每当其中一个通过时,我想用下一个最接近的日期替换它。我可能需要稍后添加更多位置,但我仍需要在输出中显示前3个即将到来的日期。我应该以不同的方式构建我的数组吗?

任何帮助将不胜感激 感谢

$event_dates = array(
    'location-1' => array(
        'date1' => array(
            'start' =>  date('m-d-Y',strtotime('2017-7-30')),
            'end'   =>  date('m-d-Y',strtotime('2017-8-3')),
        ),

        'date2' => array(
            'start' =>  date('m-d-Y',strtotime('2018-2-18')),
            'end'   =>  date('m-d-Y',strtotime('2018-2-23')),
        ), 
        'date3' => array(
            'start' =>  date('m-d-Y',strtotime('2018-7-29')),
            'end'   =>  date('m-d-Y',strtotime('2018-8-2')),
        ), 
        'date4' => array(
            'start' =>  date('m-d-Y',strtotime('2019-1-27')),
            'end'   =>  date('m-d-Y',strtotime('2019-1-31')),
        ),
        'date5' => array(
            'start' =>  date('m-d-Y',strtotime('2019-7-28')),
            'end'   =>  date('m-d-Y',strtotime('2019-8-12')),
        ), 
        'date6' => array(
            'start' =>  date('m-d-Y',strtotime('2020-1-16')),
            'end'   =>  date('m-d-Y',strtotime('2020-1-22')),
        )   
    ),

'location-2' => array(
        'date1' => array(
            'start' =>  date('m-d-Y',strtotime('2017-7-30')),
            'end'   =>  date('m-d-Y',strtotime('2017-8-13')),
        ),

        'date2' => array(
            'start' =>  date('m-d-Y',strtotime('2018-1-8')),
            'end'   =>  date('m-d-Y',strtotime('2018-2-11')),
        ), 
        'date3' => array(
            'start' =>  date('m-d-Y',strtotime('2018-7-23')),
            'end'   =>  date('m-d-Y',strtotime('2018-8-12')),
        ), 
        'date4' => array(
            'start' =>  date('m-d-Y',strtotime('2019-1-17')),
            'end'   =>  date('m-d-Y',strtotime('2019-1-23')),
        ),
        'date5' => array(
            'start' =>  date('m-d-Y',strtotime('2020-6-16')),
            'end'   =>  date('m-d-Y',strtotime('2020-6-22')),
        )
),

 'location-3' => array(
        'date1' => array(
            'start' =>  date('m-d-Y',strtotime('2017-5-12')),
            'end'   =>  date('m-d-Y',strtotime('2017-5-19')),
        ),

        'date2' => array(
            'start' =>  date('m-d-Y',strtotime('2018-9-22')),
            'end'   =>  date('m-d-Y',strtotime('2018-9-28')),
        ), 
        'date3' => array(
            'start' =>  date('m-d-Y',strtotime('2018-3-12')),
            'end'   =>  date('m-d-Y',strtotime('2018-3-20')),
        ), 
        'date4' => array(
            'start' =>  date('m-d-Y',strtotime('2019-12-9')),
            'end'   =>  date('m-d-Y',strtotime('2019-12-15')),
        ),
        'date5' => array(
            'start' =>  date('m-d-Y',strtotime('2020-11-16')),
            'end'   =>  date('m-d-Y',strtotime('2020-11-20')),
        )
));

1 个答案:

答案 0 :(得分:0)

DateTime来救援!

代码(Demo):

$TZ=new DateTimeZone('UTC');  // make some sort of declaration on timezone
$today=new DateTime('NOW',$TZ);
$today->setTime(0,0,0);    

foreach($event_dates as $locname=>$datearray){
    foreach($datearray as $eventname=>$eventarray){  // I recommend changing 'date{n}' to an actual eventname in the array
        $end=DateTime::createFromFormat('m-d-Y',$eventarray['end'],$TZ)->setTime(0,0,0);
        if($today<=$end){
            echo "$locname's $eventname";
            $start=DateTime::createFromFormat('m-d-Y',$eventarray['start'],$TZ)->setTime(0,0,0);
            $days=abs($today->diff($start)->days);
            if($today==$start){
                echo " begins today!";
            }elseif($today==$end){
                echo " concludes today!";
            }elseif($today<$start){
                echo " starts in $days day",($days!=1?"s":"");
            }else{
                echo " is in progress for $days day",($days!=1?"s":"");
            }
            echo "\n";
            break;
        }
    }
}

输出:

location-1's date1 starts in 114 days
location-2's date1 starts in 114 days
location-3's date1 starts in 35 days

为了尝试提供最强大的代码,我选择将我的方法转换为一个功能,允许指定要显示的事件日期数。另外,我发现location-3有一个日期不按顺序,所以我已经包含了一个sort()来纠正这个。

代码:(Demo

// for this sample array, $count=6 is the same as $count=-1
function currentAndUpcomingEvents($array,$location,$count=-1){ // default to -1 which will show all
    $result=[];
    $x=0;
    $TZ=new DateTimeZone('UTC');  // make some sort of declaration on timezone
    $today=new DateTime('NOW',$TZ);
    $today->setTime(0,0,0);
    // test a specific date: $today=DateTime::createFromFormat('m-d-Y','08-13-2017',$TZ)->setTime(0,0,0);

    foreach($array[$location] as $eventname=>$daterange){
        if($x==$count){break;}
        $end=DateTime::createFromFormat('m-d-Y',$daterange['end'],$TZ)->setTime(0,0,0);
        if($today<=$end){
            $start=DateTime::createFromFormat('m-d-Y',$daterange['start'],$TZ)->setTime(0,0,0);
            $days=abs($today->diff($start)->days);
            $result[$days]="$location's $eventname";  // using $days as keys will allow sorting
            if($today==$start){
                $result[$days].=" begins today!";
            }elseif($today==$end){
                $result[$days].=" concludes today!";
            }elseif($today<$start){
                $result[$days].=" starts in $days day".($days!=1?"s":"");
            }else{
                $result[$days].=" is in progress for $days day".($days!=1?"s":"");
            }
        }
        ++$x;
    }    
    ksort($result);  // location-3's date3 was originally out of order
    return $result;
}

foreach(array_keys($event_dates) as $location){
    echo implode("\n",currentAndUpcomingEvents($event_dates,$location,6));  // whole array, level1 key, events per location count
    echo "\n\n";
}

输出:

location-1's date1 starts in 114 days
location-1's date2 starts in 317 days
location-1's date3 starts in 478 days
location-1's date4 starts in 660 days
location-1's date5 starts in 842 days
location-1's date6 starts in 1014 days

location-2's date1 starts in 114 days
location-2's date2 starts in 276 days
location-2's date3 starts in 472 days
location-2's date4 starts in 650 days
location-2's date5 starts in 1166 days

location-3's date1 starts in 35 days
location-3's date3 starts in 339 days
location-3's date2 starts in 533 days
location-3's date4 starts in 976 days
location-3's date5 starts in 1319 days