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 孟德尔随机化怎样画共定位分析图
  • ¥18 模拟电路问题解答有偿速度
  • ¥15 CST仿真别人的模型结果仿真结果S参数完全不对
  • ¥15 误删注册表文件致win10无法开启
  • ¥15 请问在阿里云服务器中怎么利用数据库制作网站
  • ¥60 ESP32怎么烧录自启动程序
  • ¥50 html2canvas超出滚动条不显示
  • ¥15 java业务性能问题求解(sql,业务设计相关)
  • ¥15 52810 尾椎c三个a 写蓝牙地址
  • ¥15 elmos524.33 eeprom的读写问题