dongtiao2976 2017-03-24 15:35
浏览 26
已采纳

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

so here is what I'm trying to do. I have structured a list of locations and dates in an multi-dim array. and I want to show the next 3 upcoming dates in the output based on date and location. Also I need to show only one date per location at any given moment so basically the closest date from location 1, 2 and 3 and so on, and every time one of them is passed I want to replace it with the next closest one. I might need to add more location later on but I still need to show the first 3 upcoming dates on the output. Should I structure my array differently?

Any help would be appreciated
Thanks

$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条回答 默认 最新

  • dri98076 2017-04-07 05:34
    关注

    It's DateTime to the rescue!

    Code (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 "
    ";
                break;
            }
        }
    }
    

    Output:

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

    In an attempt to offer the most robust code, I've elected to turn my method into a function that will allow the designation of how many event dates to display. Also, I discovered that location-3 had one date out of order, so I've included a sort() to correct this.

    Code: (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("
    ",currentAndUpcomingEvents($event_dates,$location,6));  // whole array, level1 key, events per location count
        echo "
    
    ";
    }
    

    Output:

    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
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 乌班图ip地址配置及远程SSH
  • ¥15 怎么让点阵屏显示静态爱心,用keiluVision5写出让点阵屏显示静态爱心的代码,越快越好
  • ¥15 PSPICE制作一个加法器
  • ¥15 javaweb项目无法正常跳转
  • ¥15 VMBox虚拟机无法访问
  • ¥15 skd显示找不到头文件
  • ¥15 机器视觉中图片中长度与真实长度的关系
  • ¥15 fastreport table 怎么只让每页的最下面和最顶部有横线
  • ¥15 R语言卸载之后无法重装,显示电脑存在下载某些较大二进制文件行为,怎么办
  • ¥15 java 的protected权限 ,问题在注释里