PHP:返回数组中两个日期之间的所有日期

Hyd*_*erA 219 php datetime date-range

预期投入:

getDatesFromRange( '2010-10-01', '2010-10-05' );
Run Code Online (Sandbox Code Playgroud)

预期产出:

Array( '2010-10-01', '2010-10-02', '2010-10-03', '2010-10-04', '2010-10-05' )
Run Code Online (Sandbox Code Playgroud)

小智 395

您还可以查看DatePeriod类:

$period = new DatePeriod(
     new DateTime('2010-10-01'),
     new DateInterval('P1D'),
     new DateTime('2010-10-05')
);
Run Code Online (Sandbox Code Playgroud)

哪个应该为您提供DateTime对象的数组.

迭代

foreach ($period as $key => $value) {
    //$value->format('Y-m-d')       
}
Run Code Online (Sandbox Code Playgroud)

  • ...或者,事实证明,您可以使用`iterator_to_array($ period)`来获取数组.这个函数适用于`DateInterval`可用的所有PHP版本. (47认同)
  • `foreach($ period as $ date){$ array [] = $ date-> format('Ym-d'); }`将生成所需的数组. (34认同)
  • 请注意,这不会_quite_获取一个`DateTime`对象数组; 它会为您提供一个实现`Traversable`接口的`DatePeriod`对象.如果你只是计划用`foreach`迭代一个日期列表,那很好; 但除此之外,你还需要使用`foreach`来构建自己的数组. (17认同)
  • 要包括结束日期,你需要添加时间,例如`new DateTime('2010-10-05 23:59:59')` (14认同)
  • 尽管它是一段很好的代码,但是`DatePeriod`类排除了结束日期.`$ period`不包括'2010-10-05'.您可以使用第4个参数`DatePeriod :: EXCLUDE_START_DATE`排除开始日期.最后,它甚至没有返回一个字符串数组(如所要求的那样).很好的答案,但错误的问题. (13认同)
  • 在结果中包含`end date`只需使用:$ end_date = new DateTime($ end.'+ 1d'); (5认同)
  • 因为...它只能从PHP 5> = 5.3.0获得 (4认同)
  • 此代码不会产生正确的结果...最后一个日期不包含在DatePeriod日期中,我不知道为什么!你可以帮帮我吗? (4认同)

Rob*_*itt 148

function createDateRangeArray($strDateFrom,$strDateTo)
{
    // takes two dates formatted as YYYY-MM-DD and creates an
    // inclusive array of the dates between the from and to dates.

    // could test validity of dates here but I'm already doing
    // that in the main script

    $aryRange=array();

    $iDateFrom=mktime(1,0,0,substr($strDateFrom,5,2),     substr($strDateFrom,8,2),substr($strDateFrom,0,4));
    $iDateTo=mktime(1,0,0,substr($strDateTo,5,2),     substr($strDateTo,8,2),substr($strDateTo,0,4));

    if ($iDateTo>=$iDateFrom)
    {
        array_push($aryRange,date('Y-m-d',$iDateFrom)); // first entry
        while ($iDateFrom<$iDateTo)
        {
            $iDateFrom+=86400; // add 24 hours
            array_push($aryRange,date('Y-m-d',$iDateFrom));
        }
    }
    return $aryRange;
}
Run Code Online (Sandbox Code Playgroud)

来源:http://boonedocks.net/mike/archives/137-Creating-a-Date-Range-Array-with-PHP.html


ali*_*gur 132

这非常灵活.

/**
 * Creating date collection between two dates
 *
 * <code>
 * <?php
 * # Example 1
 * date_range("2014-01-01", "2014-01-20", "+1 day", "m/d/Y");
 *
 * # Example 2. you can use even time
 * date_range("01:00:00", "23:00:00", "+1 hour", "H:i:s");
 * </code>
 *
 * @author Ali OYGUR <alioygur@gmail.com>
 * @param string since any date, time or datetime format
 * @param string until any date, time or datetime format
 * @param string step
 * @param string date of output format
 * @return array
 */
function date_range($first, $last, $step = '+1 day', $output_format = 'd/m/Y' ) {

    $dates = array();
    $current = strtotime($first);
    $last = strtotime($last);

    while( $current <= $last ) {

        $dates[] = date($output_format, $current);
        $current = strtotime($step, $current);
    }

    return $dates;
}
Run Code Online (Sandbox Code Playgroud)

  • 绝对简单而辉煌!我很想看到这个解决方案和面向对象之间的Web请求内存和速度比较. (2认同)

Max*_*ime 36

请注意,ViNce提供的答案不包括该期间的结束日期.

如果您使用的是PHP 5.3+,最好的办法是使用这样的函数:

/**
 * Generate an array of string dates between 2 dates
 *
 * @param string $start Start date
 * @param string $end End date
 * @param string $format Output format (Default: Y-m-d)
 *
 * @return array
 */
function getDatesFromRange($start, $end, $format = 'Y-m-d') {
    $array = array();
    $interval = new DateInterval('P1D');

    $realEnd = new DateTime($end);
    $realEnd->add($interval);

    $period = new DatePeriod(new DateTime($start), $interval, $realEnd);

    foreach($period as $date) { 
        $array[] = $date->format($format); 
    }

    return $array;
}
Run Code Online (Sandbox Code Playgroud)

然后,您将按预期调用该函数:

getDatesFromRange('2010-10-01', '2010-10-05');
Run Code Online (Sandbox Code Playgroud)

Run demo

关于DatePeriod类的注意事项:您可以使用DatePeriod的第4个参数来排除开始日期(DatePeriod::EXCLUDE_START_DATE),但此时您不能包含结束日期.

  • 我使用了社区支持的提供的代码,并花时间调试并找出它不工作的原因。目标是避免其他用户将时间花在不起作用的“漂亮代码”上,并提供真实完整的答案。令人遗憾的是,我的编辑在一个被点赞的答案中被删除了,该答案误导了社区,因为人们在没有测试的情况下就点赞了。这不是关于我的答案,而是关于 THE 答案。反正... (3认同)

小智 22

简单但喜欢魅力:

    $period = new DatePeriod(new DateTime('2015-01-01'), new DateInterval('P1D'), new DateTime('2015-01-15 +1 day'));
    foreach ($period as $date) {
        $dates[] = $date->format("Y-m-d");
    }

    //ONLY SHOWING
    echo '<pre>';
    var_dump($dates);
    echo '</pre>';
    exit();
Run Code Online (Sandbox Code Playgroud)


Hai*_*vgi 12

看看这个

  function GetDays($sStartDate, $sEndDate){  
      // Firstly, format the provided dates.  
      // This function works best with YYYY-MM-DD  
      // but other date formats will work thanks  
      // to strtotime().  
      $sStartDate = gmdate("Y-m-d", strtotime($sStartDate));  
      $sEndDate = gmdate("Y-m-d", strtotime($sEndDate));  

      // Start the variable off with the start date  
     $aDays[] = $sStartDate;  

     // Set a 'temp' variable, sCurrentDate, with  
     // the start date - before beginning the loop  
     $sCurrentDate = $sStartDate;  

     // While the current date is less than the end date  
     while($sCurrentDate < $sEndDate){  
       // Add a day to the current date  
       $sCurrentDate = gmdate("Y-m-d", strtotime("+1 day", strtotime($sCurrentDate)));  

       // Add this new day to the aDays array  
       $aDays[] = $sCurrentDate;  
     }  

     // Once the loop has finished, return the  
     // array of days.  
     return $aDays;  
   }  
Run Code Online (Sandbox Code Playgroud)

用得像

GetDays('2007-01-01', '2007-01-31'); 
Run Code Online (Sandbox Code Playgroud)


dro*_*lex 12

这很简单,很甜,应该可以在PHP4 +中使用.

function getDatesFromRange($start, $end){
    $dates = array($start);
    while(end($dates) < $end){
        $dates[] = date('Y-m-d', strtotime(end($dates).' +1 day'));
    }
    return $dates;
}
Run Code Online (Sandbox Code Playgroud)


Luk*_*kas 8

完成这项工作的很多方法,但最终都取决于您使用的PHP版本.以下是所有解决方案的摘要:

获取PHP版本:

echo phpinfo();
Run Code Online (Sandbox Code Playgroud)

PHP 5.3+

$period = new DatePeriod(
     new DateTime('2010-10-01'),
     new DateInterval('P1D'),
     new DateTime('2010-10-05')
);
Run Code Online (Sandbox Code Playgroud)

PHP 4+

/**
 * creating between two date
 * @param string since
 * @param string until
 * @param string step
 * @param string date format
 * @return array
 * @author Ali OYGUR <alioygur@gmail.com>
 */
function dateRange($first, $last, $step = '+1 day', $format = 'd/m/Y' ) { 

    $dates = array();
    $current = strtotime($first);
    $last = strtotime($last);

    while( $current <= $last ) { 

        $dates[] = date($format, $current);
        $current = strtotime($step, $current);
    }

    return $dates;
}
Run Code Online (Sandbox Code Playgroud)

PHP <4

你应该升级:)


nzn*_*nzn 7

功能短.PHP 5.3及以上.可以采取strtotime可以理解的任何日期格式的可选第三个参数.结束<开始时自动反转方向.

function getDatesFromRange($start, $end, $format='Y-m-d') {
    return array_map(function($timestamp) use($format) {
        return date($format, $timestamp);
    },
    range(strtotime($start) + ($start < $end ? 4000 : 8000), strtotime($end) + ($start < $end ? 8000 : 4000), 86400));
}
Run Code Online (Sandbox Code Playgroud)

测试:

date_default_timezone_set('Europe/Berlin');
print_r(getDatesFromRange( '2016-7-28','2016-8-2' ));
print_r(getDatesFromRange( '2016-8-2','2016-7-28' ));
print_r(getDatesFromRange( '2016-10-28','2016-11-2' ));
print_r(getDatesFromRange( '2016-11-2','2016-10-28' ));
print_r(getDatesFromRange( '2016-4-2','2016-3-25' ));
print_r(getDatesFromRange( '2016-3-25','2016-4-2' ));
print_r(getDatesFromRange( '2016-8-2','2016-7-25' ));
print_r(getDatesFromRange( '2016-7-25','2016-8-2' ));
Run Code Online (Sandbox Code Playgroud)

输出:

Array ( [0] => 2016-07-28 [1] => 2016-07-29 [2] => 2016-07-30 [3] => 2016-07-31 [4] => 2016-08-01 [5] => 2016-08-02 ) 
Array ( [0] => 2016-08-02 [1] => 2016-08-01 [2] => 2016-07-31 [3] => 2016-07-30 [4] => 2016-07-29 [5] => 2016-07-28 ) 
Array ( [0] => 2016-10-28 [1] => 2016-10-29 [2] => 2016-10-30 [3] => 2016-10-31 [4] => 2016-11-01 [5] => 2016-11-02 ) 
Array ( [0] => 2016-11-02 [1] => 2016-11-01 [2] => 2016-10-31 [3] => 2016-10-30 [4] => 2016-10-29 [5] => 2016-10-28 ) 
Array ( [0] => 2016-04-02 [1] => 2016-04-01 [2] => 2016-03-31 [3] => 2016-03-30 [4] => 2016-03-29 [5] => 2016-03-28 [6] => 2016-03-27 [7] => 2016-03-26 [8] => 2016-03-25 ) 
Array ( [0] => 2016-03-25 [1] => 2016-03-26 [2] => 2016-03-27 [3] => 2016-03-28 [4] => 2016-03-29 [5] => 2016-03-30 [6] => 2016-03-31 [7] => 2016-04-01 [8] => 2016-04-02 ) 
Array ( [0] => 2016-08-02 [1] => 2016-08-01 [2] => 2016-07-31 [3] => 2016-07-30 [4] => 2016-07-29 [5] => 2016-07-28 [6] => 2016-07-27 [7] => 2016-07-26 [8] => 2016-07-25 ) 
Array ( [0] => 2016-07-25 [1] => 2016-07-26 [2] => 2016-07-27 [3] => 2016-07-28 [4] => 2016-07-29 [5] => 2016-07-30 [6] => 2016-07-31 [7] => 2016-08-01 [8] => 2016-08-02 )
Run Code Online (Sandbox Code Playgroud)


小智 7

必须添加$ end-> modify('+ 1 day') 以包括间隔的最后一天,例如,一月将使用31天而不是30天,而无需使用Modify()方法。此版本的代码将包含间隔的最后一天:

$begin = new DateTime( '2018-08-01' );
$end = new DateTime( '2018-08-31' );
$end = $end->modify( '+1 day' ); 

$interval = new DateInterval('P1D');
$daterange = new DatePeriod($begin, $interval ,$end);

foreach($daterange as $date){
    echo $date->format("Ymd") . "<br>";
}
Run Code Online (Sandbox Code Playgroud)

PHP文档链接


Gaz*_*ler 5

<?
print_r(getDatesFromRange( '2010-10-01', '2010-10-05' ));

function getDatesFromRange($startDate, $endDate)
{
    $return = array($startDate);
    $start = $startDate;
    $i=1;
    if (strtotime($startDate) < strtotime($endDate))
    {
       while (strtotime($start) < strtotime($endDate))
        {
            $start = date('Y-m-d', strtotime($startDate.'+'.$i.' days'));
            $return[] = $start;
            $i++;
        }
    }

    return $return;
}
Run Code Online (Sandbox Code Playgroud)


Gla*_*vić 5

这是一个函数,它将返回两个方向的日期范围,它适用于PHP> = 5.2.2:

function createRange($start, $end, $format = 'Y-m-d') {
    $start  = new DateTime($start);
    $end    = new DateTime($end);
    $invert = $start > $end;

    $dates = array();
    $dates[] = $start->format($format);
    while ($start != $end) {
        $start->modify(($invert ? '-' : '+') . '1 day');
        $dates[] = $start->format($format);
    }
    return $dates;
}
Run Code Online (Sandbox Code Playgroud)

使用示例:

print_r(createRange('2010-10-01', '2010-10-05'));
/*Array
(
    [0] => 2010-10-01
    [1] => 2010-10-02
    [2] => 2010-10-03
    [3] => 2010-10-04
    [4] => 2010-10-05
)*/

print_r(createRange('2010-10-05', '2010-10-01', 'j M Y'));
/*Array
(
    [0] => 5 Oct 2010
    [1] => 4 Oct 2010
    [2] => 3 Oct 2010
    [3] => 2 Oct 2010
    [4] => 1 Oct 2010
)*/
Run Code Online (Sandbox Code Playgroud)

demo


Nir*_*hoi 5

// Specify the start date. This date can be any English textual format  
$date_from = "2018-02-03";   
$date_from = strtotime($date_from); // Convert date to a UNIX timestamp  

// Specify the end date. This date can be any English textual format  
$date_to = "2018-09-10";  
$date_to = strtotime($date_to); // Convert date to a UNIX timestamp  

// Loop from the start date to end date and output all dates inbetween  
for ($i=$date_from; $i<=$date_to; $i+=86400) {  
    echo date("Y-m-d", $i).'<br />';  
} 
Run Code Online (Sandbox Code Playgroud)