2011-03-06 153 views
8

我試圖通過PHP來循環日期。目前我的代碼被卡在循環110307中。我需要日期格式在yymmdd中。以下是我嘗試使用:通過PHP循環遍歷日期

<?php 
    $check_date = '100227'; 
    $end_date = '100324'; 

    while($check_date != $end_date){ 
     $check_date = date("ymd", strtotime("+1 day", strtotime($check_date))); 
     echo $check_date . '<br>'; 
    } 
?> 
+0

什麼是PHP版本? – 2011-03-06 06:20:14

+0

@Itay Moav:版本5.2.17。 – shinjuo 2011-03-06 06:23:11

+0

然後而不是'modify('+ 1 day');'例如,你可以使用' - > add'方法。 – 2011-03-06 06:36:56

回答

5

strtotime解釋 「100227」 作爲時間10時02分27秒的今天,不是2010-02-27。所以在第一步之後,$check_date(今天)是「110307」。在隨後的所有步驟中,「110307」再次被解釋爲今天的時間,將$check_date再次解釋爲「110307」。

用於重複日期的絕招是利用mktime的正常化日期的能力,這樣的事情:

$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

我沒有真正使用你給我的代碼,但你的問題原因幫助我找到了解決方案。感謝所有的幫助 – shinjuo 2011-03-07 01:12:54

+1

解釋是重要的部分。 – Anomie 2011-03-07 01:49:17

2

下面是我用的是代碼的一部分,或許可以得到改善,取決於你使用的PHP版本。

//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 
+2

哇,這是超重量級。 – 2011-03-06 06:30:32

+0

@Paul Schreiber閱讀整個事情,它是一個更大的框架/ lib的一部分。重要的是,你是對的,因爲我需要針對不同的週期準確地使用相同的代碼(它是事件中繼器計算器的一部分)。但是......把它放在這裏花的時間比寫下它的時間少:-) – 2011-03-06 06:33:13

+0

我可以看到。似乎有一個很大的性能影響,可以導入一個框架並分配/實例化/銷燬n個對象。 – 2011-03-06 06:34:54

8

嘗試使用unix時間戳並每次添加86400。這要比致電strtotime()快。你可以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

日期格式需要保留爲yymmdd或至少它會以那樣的方式啓動,因此需要在我的代碼中使用 – shinjuo 2011-03-06 06:32:07

+0

您可以在循環外部快速進行轉換,這比做(O(1))更便宜它每次迭代(O(n))。 – 2011-03-06 06:33:29

+0

由於夏令時間爲23或25小時,因此一天中不得使用86400秒! – sbrbot 2014-08-30 18:08:17

3

以下是我喜歡做它:

$startDate = new DateTime('20100227'); 
$endDate = new DateTime('20100324'); 

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

我覺得這個人更清潔,它不需要像84600那樣硬編碼值。