PHP - Is there a simple way to loop between two dates and fill in missing values?

前端 未结 6 1406
轻奢々
轻奢々 2020-12-17 04:34

I have 2 dates. Lets say they look like this.

$start = 2010/12/24;
$end = 2012/01/05;

I query the database to look for visits between these

相关标签:
6条回答
  • 2020-12-17 05:02

    If you're using PHP5.3 then Mark Baker's answer is the one to use. If (as you say in your comment) you're still on PHP5.2 something like this should help you:

    $startdate = strtotime( '2010/12/24' );
    $enddate = strtotime( '2012/01/05' );
    $loopdate = $startdate;
    $datesArray = array();
    while( $loopdate <= $enddate ) {
       $datesArray[$loopdate] = 0;
       $loopdate = strtotime( '+1 day', $loopdate );
    }
    

    It will create an array of the unix timestamp of every date between the start and end dates as the index and each value set to zero. You can then overwrite any actual results you have with the correct values.

    0 讨论(0)
  • 2020-12-17 05:09

    I would calculate the difference between start and end date in days, iterate on that adding a day to the timestamp on each iteration.

    $start = strtotime("2010/12/24");
    $end = strtotime("2012/01/05");
    
    // start and end are seconds, so I convert it to days 
    $diff = ($end - $start) / 86400; 
    
    for ($i = 1; $i < $diff; $i++) {
        // just multiply 86400 and add it to $start
        // using strtotime('+1 day' ...) looks nice but is expensive.
        // you could also have a cumulative value, but this was quicker
        // to type
        $date = $start + ($i * 86400); 
    
        echo date('r', $date);
    }
    
    0 讨论(0)
  • 2020-12-17 05:13
    $i = 1;
    while(date("Y/m/d", strtotime(date("Y/m/d", strtotime($start)) . "+ $i days")) < $end) {
        ... code here ...
        $i++;
    }
    
    0 讨论(0)
  • 2020-12-17 05:21
    $start_date = DateTime::createFromFormat('Y/m/d', '2010/12/24');
    $end_date = DateTime::createFromFormat('Y/m/d', '2012/01/05');
    
    $current_date = $start_date;
    
    while($current_date <= $end_date) {
        $current_date = $current_date->add(new DateInterval('P1D'));
        // do your array work here.
    }
    

    See DateTime::add() for more information about this.

    0 讨论(0)
  • 2020-12-17 05:21

    I have this bit of horrible code saved:

    while (($tmptime = strtotime('+' . (int) $d++ . ' days', strtotime($from))) && ($tmptime <= strtotime($to)))    // this code makes baby jesus cry
        $dates[strftime('%Y-%m-%d', $tmptime)] = 0;
    

    (Set $from and $to to appropriate values.) It may well make you cry, too - but it sort of works.

    The proper way to do it is to use DateInterval, of course.

    0 讨论(0)
  • 2020-12-17 05:27

    Just to demonstrate the power of some of PHP's newer interval handling method (mentioned by pgl in his answer):

    $startDate = DateTime::createFromFormat("Y/m/d","2010/12/24",new DateTimeZone("Europe/London"));
    $endDate = DateTime::createFromFormat("Y/m/d","2012/01/05",new DateTimeZone("Europe/London"));
    
    $periodInterval = new DateInterval( "P1D" ); // 1-day, though can be more sophisticated rule
    $period = new DatePeriod( $startDate, $periodInterval, $endDate );
    
    foreach($period as $date){
       echo $date->format("Y-m-d") , PHP_EOL;
    }
    

    Does require PHP >= 5.3.0

    EDIT

    If you need to include the actual end date, then you need to add a day to $endDate immediately before the foreach() loop:

    $endDate->add( $periodInterval );
    

    EDIT #2

    $startDate = new DateTime("2010/12/24",new DateTimeZone("Europe/London"));
    $endDate = new DateTime("2012/01/05",new DateTimeZone("Europe/London"));
    
    do {
       echo $startDate->format("Y-m-d") , PHP_EOL;
       $startDate->modify("+1 day");
    } while ($startDate <= $endDate);
    

    For PHP 5.2.0 (or earlier if dateTime objects are enabled)

    0 讨论(0)
提交回复
热议问题