2015-05-04 221 views
-2

我需要顯示的日期範圍如下所示:如何將兩個日期縮小到一個日期範圍?

  • 5月5-7日,2015年
  • 4月29日至5月五日,2015年
  • 2015年12月30日 - 2016年1月1日

我提供了一個開始日期和結束日期作爲PHP日期對象。有沒有一種方法可以解析那些用PHP輸出的需要?


編輯:我想你們都誤會我在尋找什麼做的。

我有一個WordPress事件插件,輸出開始日期和結束日期。如果事件有2015年5月4日的開始日期,2015年5月7日的結束日期,我需要顯示此:

<h4>Event Title</h4> 
<p>When: <time>May 4-7, 2015</time></p> 

我不需要顯示給定日期之間的每個日期;這對我來說很簡單,我自己就可以搞清楚。


編輯2:好吧,只是爲了確保我是完全清楚:

我使用Tri.be活動插件允許用戶創建事件的日曆。在這個WordPress站點的首頁上,我需要顯示即將發生的事件列表。每個事件應該是輸出這樣的:

此事件應該是輸出這樣的:

<article> 
    <h4><a href="/path/to/event/">Systematic Implementation of Advance Care Planning in a Diverse City</a></h4> 
    <p> 
     <a href="/path/to/event/"> 
      Aging in America Conference - Chicago, IL<br /> 
      <time datetime="2015-03-23">March 23-27, 2015</time> 
     </a> 
    </p> 
</article> 

我遇到的麻煩的一點是<time>元素。以下答案似乎表明我想以此格式輸出時間:

<time datetime="2015-03-23">March 23, 2015 - March 27, 2015</time> 

這是不正確的。如果是這種情況,我可以輕鬆地自行輸出。正確的格式爲:

<time datetime="2015-03-23">March 23-27, 2015</time> 

因此,問題是:「我如何才能縮小兩個日期中的一個日期範圍」

+0

你檢查http://php.net/manual/en/class.datetime.php? – sitilge

+0

https://php.net/manual/en/book.datetime.php –

+0

是的,我檢查了手冊,並沒有提供我所需要的。請參閱最新的問題。 – JacobTheDev

回答

1

編輯2:

我已經更新了一些日期格式的功能。

輸出將是:

事件標題

時間:2010年2月28日 - 2010年3月2日

事件標題

時間:3月4 2010 - Mar 5,2010

事件標題

時間:2010年12月31日 - 2011年1月5日

編輯:

我發現這(通過搜索) - >Check for consecutive dates within a set and return as range

的下面的代碼不是我的。這是一箇舊帖子從@Darragh

我已經對代碼進行了一些小修改以適應OP的問題。

// assuming a chronologically 
    // ordered array of DateTime objects 

    $dates = array(   
      new DateTime('2010-02-28'), 
      new DateTime('2010-03-01'), 
      new DateTime('2010-03-02'), 
      new DateTime('2010-03-04'), 
      new DateTime('2010-03-05'), 
      new DateTime('2010-12-31'), 
      new DateTime('2011-01-01'), 
      new DateTime('2011-01-02'), 
      new DateTime('2011-01-03'), 
      new DateTime('2011-01-04'), 
      new DateTime('2011-01-05'), 
    ); 

    // process the array 

    $lastDate = null; 
    $ranges = array(); 
    $currentRange = array(); 

    foreach ($dates as $date) {  

     if (null === $lastDate) { 
      $currentRange[] = $date; 
     } else { 

      // get the DateInterval object 
      $interval = $date->diff($lastDate); 

      // DateInterval has properties for 
      // days, weeks. months etc. You should 
      // implement some more robust conditions here to 
      // make sure all you're not getting false matches 
      // for diffs like a month and a day, a year and 
      // a day and so on... 

      if ($interval->days === 1) { 
       // add this date to the current range 
       $currentRange[] = $date;  
      } else { 
       // store the old range and start anew 
       $ranges[] = $currentRange; 
       $currentRange = array($date); 
      } 
     } 

     // end of iteration... 
     // this date is now the last date  
     $lastDate = $date; 
    } 

    // messy... 
    $ranges[] = $currentRange; 

    // print dates 

     foreach ($ranges as $range) { 

    // there'll always be one array element, so 
    // shift that off and create a string from the date object 
    $startDate = array_shift($range); 
    $str = "<h4>Event title</h4>"; 
    $str .= "<p>When: "; 
    $str .= "<time>"; 
    $str .= sprintf('%s', $startDate->format('M j, Y')); 
    // if there are still elements in $range 
    // then this is a range. pop off the last 
    // element, do the same as above and concatenate 
    if (count($range)) { 
     $endDate = array_pop($range); 
     $str .= sprintf(' - %s', $endDate->format('M j, Y')); 
     $str .= "</time></p>"; 
    } 

    echo "<p>$str</p>"; 
} 

(基於原來的問題)舊答案

$start_date = new DateTime('2015-05-01'); 
$end_date = new DateTime('2015-05-04'); 
$end_date = $end_date->modify('+1 day'); 

$interval = new DateInterval('P1D'); 
$daterange = new DatePeriod($start_date, $interval ,$end_date); 

foreach($daterange as $date){ 
    echo $date->format("M d, Y") . "<br>"; 
} 

// Output 
// May 01, 2015 
// May 02, 2015 
// May 03, 2015 
// May 04, 2015 
+0

很確定你錯誤地理解了我所尋找的所有其他人顯然有更新的問題更清楚 – JacobTheDev

+1

爲什麼downvote?我幫你,你downvote。更清楚你想要什麼。 – Per76

+0

因爲它回答的問題與我提出的問題不同,請參閱更新後的問題 – JacobTheDev

0

這將是最簡單的解決方案:

$dtStart = new DateTime('2015-05-05'); 
$dtEnd = new DateTime('2015-05-07'); 

while ($dtStart <= $dtEnd) { 
    echo $dtStart->format('Y-m-d') . "\n"; 
    $dtStart->modify('+1 day'); 
} 

// Output: 
// 2015-05-05 
// 2015-05-06 
// 2015-05-07 

$dtStart = new DateTime('2015-12-30'); 
$dtEnd = new DateTime('2016-01-01'); 

while ($dtStart <= $dtEnd) { 
    echo $dtStart->format('Y-m-d') . "\n"; 
    $dtStart->modify('+1 day'); 
} 

// Output: 
// 2015-12-30 
// 2015-12-31 
// 2016-01-01 
+0

我想你誤解了我要去的;請參閱最新的問題。 – JacobTheDev

1
<article> 
    <h4><a href="/path/to/event/">Systematic Implementation of Advance Care Planning in a Diverse City</a></h4> 
    <p> 
     <a href="/path/to/event/"> 
      Aging in America Conference - Chicago, IL<br /> 
      <time datetime="2015-03-23/2015-03-27">March 23&ndash;27 2015</time> 
     </a> 
    </p> 
</article> 

編輯

上面PHP碼完整的示例。

輸出

2015年3月23日 - 2015年3月27日

// assuming a chronologically 
    // ordered array of DateTime objects 

    $dates = array(   
      new DateTime('2015-03-23'), 
      new DateTime('2015-03-24'), 
      new DateTime('2015-03-25'), 
      new DateTime('2015-03-26'), 
      new DateTime('2015-03-27')   
    ); 

    // process the array 

    $lastDate = null; 
    $ranges = array(); 
    $currentRange = array(); 

    foreach ($dates as $date) {  

     if (null === $lastDate) { 
      $currentRange[] = $date; 
     } else { 

      // get the DateInterval object 
      $interval = $date->diff($lastDate); 

      // DateInterval has properties for 
      // days, weeks. months etc. You should 
      // implement some more robust conditions here to 
      // make sure all you're not getting false matches 
      // for diffs like a month and a day, a year and 
      // a day and so on... 

      if ($interval->days === 1) { 
       // add this date to the current range 
       $currentRange[] = $date;  
      } else { 
       // store the old range and start anew 
       $ranges[] = $currentRange; 
       $currentRange = array($date); 
      } 
     } 

     // end of iteration... 
     // this date is now the last date  
     $lastDate = $date; 
    } 

    // messy... 
    $ranges[] = $currentRange; 

    // print dates 

    foreach ($ranges as $range) { 

    // there'll always be one array element, so 
    // shift that off and create a string from the date object 
    $startDate = array_shift($range); 
    $str = "<h4>Event title</h4>"; 
    $str .= "<p>When: "; 
    $str .= "<time>"; 
    $str .= sprintf('%s', $startDate->format('M j, Y')); 
    // if there are still elements in $range 
    // then this is a range. pop off the last 
    // element, do the same as above and concatenate 
    if (count($range)) { 
     $endDate = array_pop($range); 
     $str .= sprintf(' - %s', $endDate->format('M j, Y')); 
     $str .= "</time></p>"; 
    } 

} 

echo "<time datetime=".$startDate->format('M j, Y')."/".$endDate->format('M j, Y').">".$startDate->format('M j, Y')."&ndash;".$endDate->format('M j, Y')."</time>"; 

//OUTPUT 
// Mar 23, 2015–Mar 27, 2015 
相關問題