Loop through dates with PHP

后端 未结 4 2042
粉色の甜心
粉色の甜心 2021-02-15 11:53

I am trying to loop through dates with PHP. Currently my code gets stuck in a loop repeating 110307. I need the date format to be in yymmdd. Here is what I was trying to use:

相关标签:
4条回答
  • 2021-02-15 12:03

    Here is part of a code I use, can probably be improved, depends on PHP version you use.

    //usage
    $Iterator=class Dates_DateIterator::factory('Daily',
                                               new Datetime('20100227'),
                                               new Datetime('20100324'));
    
    foreach($Iterator as $i=>$day){
        var_dump($i);
        var_dump($day);
    }
    
    
    //code lib
    abstract class Dates_DateIterator implements Iterator
    {
        /**
         * Factory method, saves some code, also enable me to put everything in the same class 
         * as we use Autoload to load classes.
         */
        static public function factory($cycle,DateTime $DateI,DateTime $DateII){
            switch($cycle){
                case 'Daily':
                    return new DaysIterator($DateI,$DateII);
                case 'Weekly':
                    return new WeeksIterator($DateI,$DateII);
                case 'Monthly':
                    return new MonthsIterator($DateI,$DateII);
                case 'Yearly':
                    return new YearsIterator($DateI,$DateII);
                default:
                    throw(new Exception('No valid cycle was chosen to iterate over'));
            }
        }
        /**
         * @var DateTime represents the start range.
         */
        public $FromDate;
        /**
         * @var DateTime represents the end range.
         */
        public $ToDate;
        /**
         * @var DateTime Current Date.
         */
        protected $CurrentDate;
    
        public function __construct(DateTime $DateI,DateTime $DateII)
        {
            if($DateII->format('U') > $DateI->format('U'))
            {
                $this->FromDate=$DateI;
                $this->ToDate=$DateII;
                $this->CurrentDate=$DateI;
            }
            else
            {
                $this->FromDate=$DateII;
                $this->ToDate=$DateI;
                $this->CurrentDate=$DateII;
            }
        }//EOF constructor
    
        /**
         * @return DateTime
         */
        public function getClonedCurrent(){
            return clone($this->CurrentDate);   
        }
    
        public function current()
        {
            return $this->CurrentDate;
        }//EOF current
    
        public function currentDate()
        {
            return $this->CurrentDate->format('Ymd');
        }//EOF current
    
        public function rewind()
        {
            $this->CurrentDate=$this->FromDate;
        }//EOF rewind
    
        public function valid()
        {
            //Kill hours/minutes/seconds. If we are to add hours and minutes iterators, we will need to rethink this.
            return (floor($this->CurrentDate->format('U')/(3600*24)) <= floor($this->ToDate->format('U')/(3600*24)));
        }//EOF valid    
    }//EOF CLASS  DateIterator
    
    
    
    
    
    
    
    
    
    class DaysIterator extends SiTEL_Dates_DateIterator
    {
        public function __construct(DateTime $DateI,DateTime $DateII)
        {
            parent::__construct($DateI,$DateII);
        }//EOF constructor
    
        public function next()
        {
            $this->CurrentDate->modify('+1 day');
        }//EOF next
    
        public function key()
        {
            return $this->CurrentDate->format('d');
        }//EOF key
    
    }//EOD CLASS DaysIterator
    
    0 讨论(0)
  • 2021-02-15 12:12

    strtotime interprets "100227" as the time 10:02:27 today, not 2010-02-27. So after the first step, $check_date (today) is "110307". At all subsequent steps "110307" is again interpreted as a time today, giving $check_date as "110307" again.

    A neat trick for iterating dates is to take advantage of mktime's ability to normalize dates, something like this:

    $date_arr = array(27,2,2010);
    $end_date = "100324";
    do {
        $check_date = gmdate('ymd', gmmktime(0,0,0,$date_arr[1],$date_arr[0]++,$date_arr[2]));
        echo $check_date."\n";
    } while($end_date!=$check_date);
    
    0 讨论(0)
  • 2021-02-15 12:19

    Try using a unix timestamp and adding 86400 each time. That's gotta be faster than calling strtotime(). You can lookup timestamp conversions online.

    <?php
        $check_date = 1267228800; // '2010-02-27';
        $end_date = 1269388800; // '2010-03-24';
    
        while($check_date != $end_date){
            $check_date += 86400;
            echo date("Ymd", $check_date) . '<br>';  
        }
    ?>
    
    0 讨论(0)
  • 2021-02-15 12:26

    Here's how I prefer to do it:

    $startDate = new DateTime('20100227');
    $endDate = new DateTime('20100324');
    
    while ($startDate <= $endDate) {
      // your code here
      ...
      // go to the next day
      $startDate->add(new DateInterval('P1D'));
    }
    

    I find this much cleaner personally, and it's nice not having to hard-code values like 84600.

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