PHP: возвращает все даты между двумя датами в массиве

Ожидаемый ввод:

getDatesFromRange( '2010-10-01', '2010-10-05' ); 

Ожидаемый результат:

 Array( '2010-10-01', '2010-10-02', '2010-10-03', '2010-10-04', '2010-10-05' ) 

Вы также можете взглянуть на класс DatePeriod :

 $period = new DatePeriod( new DateTime('2010-10-01'), new DateInterval('P1D'), new DateTime('2010-10-05') ); 

Который должен получить массив с объектами DateTime.

 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('Ym-d',$iDateFrom)); // first entry while ($iDateFrom<$iDateTo) { $iDateFrom+=86400; // add 24 hours array_push($aryRange,date('Ym-d',$iDateFrom)); } } return $aryRange; } 

источник: http://boonedocks.net/mike/archives/137-Creating-a-Date-Range-Array-with-PHP.html

Это очень гибко.

 /** * 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; } 

Обратите внимание, что ответ, предоставленный 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: Ymd) * * @return array */ function getDatesFromRange($start, $end, $format = 'Ym-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; } 

Затем вы вызываете функцию как ожидалось:

 getDatesFromRange('2010-10-01', '2010-10-05'); 

Запустить демоверсию

Примечание о классе DatePeriod : вы можете использовать 4-й параметр DatePeriod, чтобы исключить дату начала ( DatePeriod::EXCLUDE_START_DATE ), но на данный момент вы не можете DatePeriod::EXCLUDE_START_DATE дату окончания.

Простой, но как шарм:

  $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("Ymd"); } //ONLY SHOWING echo '<pre>'; var_dump($dates); echo '</pre>'; exit(); 

взгляните на это

  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("Ymd", strtotime($sStartDate)); $sEndDate = gmdate("Ymd", 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("Ymd", 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; } 

использовать как

 GetDays('2007-01-01', '2007-01-31'); 

Это короткий, сладкий, и он должен работать на PHP4 +.

 function getDatesFromRange($start, $end){ $dates = array($start); while(end($dates) < $end){ $dates[] = date('Ym-d', strtotime(end($dates).' +1 day')); } return $dates; } 

многие способы сделать это, но в конечном итоге все зависит от используемой вами версии PHP. Вот краткий обзор всех решений:

получить версию PHP:

 echo phpinfo(); 

PHP 5.3+

 $period = new DatePeriod( new DateTime('2010-10-01'), new DateInterval('P1D'), new DateTime('2010-10-05') ); 

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; } 

PHP <4

вы должны обновить 🙂

Вот функция, которая вернет диапазоны дат в обоих направлениях и работает на PHP> = 5.2.2 :

 function createRange($start, $end, $format = 'Ym-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; } 

Пример использования:

 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 )*/ 

демонстрация

Решение для PHP 5.2 с объектами DateTime. Но startDate ДОЛЖЕН быть до endDate.

 function createRange($startDate, $endDate) { $tmpDate = new DateTime($startDate); $tmpEndDate = new DateTime($endDate); $outArray = array(); do { $outArray[] = $tmpDate->format('Ym-d'); } while ($tmpDate->modify('+1 day') <= $tmpEndDate); return $outArray; } 

С помощью:

 $dates = createRange('2010-10-01', '2010-10-05'); 

$ date содержат:

 Array( '2010-10-01', '2010-10-02', '2010-10-03', '2010-10-04', '2010-10-05' ) 
 function createDateRangeArray($start, $end) { // Modified by JJ Geewax $range = array(); if (is_string($start) === true) $start = strtotime($start); if (is_string($end) === true ) $end = strtotime($end); if ($start > $end) return createDateRangeArray($end, $start); do { $range[] = date('Ym-d', $start); $start = strtotime("+ 1 day", $start); } while($start < $end); return $range; } 

Источник: http://boonedocks.net/mike/archives/137-Creating-a-Date-Range-Array-with-PHP.html

 <? 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('Ym-d', strtotime($startDate.'+'.$i.' days')); $return[] = $start; $i++; } } return $return; } 

Вот как это сделать, используя Carbon https://github.com/briannesbitt/Carbon :

 public function buildDateRangeArray($first, $last) { while ($first <= $last) { $dates[] = $first->toDateString(); $first->addDay(); } return $dates; } 

Это, конечно же, можно настроить, чтобы не использовать Carbon. Первыми и последними параметрами $, переданными функции, являются экземпляры Carbon.

Короткая функция. PHP 4 и выше. Может принимать необязательный третий параметр любого формата даты, который может обнаружить strtotime. Автоматически отменяет направление, если конец <старт.

 function getDatesFromRange($start, $end, $format='Ym-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)); } 

Контрольная работа:

 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' )); 

Вывод:

 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 ) 
 // will return dates array function returnBetweenDates( $startDate, $endDate ){ $startStamp = strtotime( $startDate ); $endStamp = strtotime( $endDate ); if( $endStamp > $startStamp ){ while( $endStamp >= $startStamp ){ $dateArr[] = date( 'Ym-d', $startStamp ); $startStamp = strtotime( ' +1 day ', $startStamp ); } return $dateArr; }else{ return $startDate; } } returnBetweenDates( '2014-09-16', '2014-09-26' ); // print_r( returnBetweenDates( '2014-09-16', '2014-09-26' ) ); 

он будет возвращать массив, как показано ниже:

 Array ( [0] => 2014-09-16 [1] => 2014-09-17 [2] => 2014-09-18 [3] => 2014-09-19 [4] => 2014-09-20 [5] => 2014-09-21 [6] => 2014-09-22 [7] => 2014-09-23 [8] => 2014-09-24 [9] => 2014-09-25 [10] => 2014-09-26 ) 
 $report_starting_date=date('2014-09-16'); $report_ending_date=date('2014-09-26'); $report_starting_date1=date('Ym-d',strtotime($report_starting_date.'-1 day')); while (strtotime($report_starting_date1)<strtotime($report_ending_date)) { $report_starting_date1=date('Ym-d',strtotime($report_starting_date1.'+1 day')); $dates[]=$report_starting_date1; } print_r($dates); // dates ('2014-09-16', '2014-09-26') //print result Array ( [0] => 2014-09-16 [1] => 2014-09-17 [2] => 2014-09-18 [3] => 2014-09-19 [4] => 2014-09-20 [5] => 2014-09-21 [6] => 2014-09-22 [7] => 2014-09-23 [8] => 2014-09-24 [9] => 2014-09-25 [10] => 2014-09-26 ) 

Вот еще одно решение. Пожалуйста, проверьте это.

 $first = '10/30/2017'; //starting date $last= '10/11/2017'; //ending date $first_time_arr=explode('/',$first); $last_time_arr=explode('/',$last); //create timestamp of starting date $start_timestamp=mktime(0,0,0, $first_time_arr[0], $first_time_arr[1],$first_time_arr[2]); //create timestamp of ending date $end_timestamp=mktime(0,0,0, $last_time_arr[0], $last_time_arr[1],$last_time_arr[2]); $date_arr=array(); for($i=$start_timestamp;$i<=$end_timestamp;$i=$i+86400){ $date_arr[]=date("Ymd",$i); //this will save all dates in array } 
 public static function countDays($date1,$date2) { $date1 = strtotime($date1); // or your date as well $date2 = strtotime($date2); $datediff = $date1 - $date2; return floor($datediff/(60*60*24)); } public static function dateRange($date1,$date2) { $count = static::countDays($date1,$date2) + 1; $dates = array(); for($i=0;$i<$count;$i++) { $dates[] = date("Ymd",strtotime($date2.'+'.$i.' days')); } return $dates; } 
 function datesbetween ($date1,$date2) { $dates= array(); for ($i = $date1 ; $i<= $date1 ; $i=date_add($i, date_interval_create_from_date_string('1 days')) ) { $dates[] = clone $i; } return $dates; } 

Я думаю, что это самый короткий ответ

Редактируйте код, как вам нравится

 for ($x=strtotime('2015-12-01');$x<=strtotime('2015-12-30');$x+=86400) echo date('Ym-d',$x); 

Мне нравится сплошной лайнер!

Мое открытие php дня состояло в том, что array_push() возвращает новое количество элементов в массиве.

Мне удалось проверить совпадение даты окончания, прирастить $ x и нажимать новые элементы в рамках двухчастного оператора состояния пустого цикла while.

 function getDatesFromRange($a,$b,$x=0,$dates=[]){ while(end($dates)!=$b && $x=array_push($dates,date("Ymd",strtotime("$a +$x day")))); return $dates; } var_export(getDatesFromRange('2010-10-01','2010-10-05')); 

Наиболее похожей функцией моей на этой странице является drolex (которой я на самом деле не нашел до тех пор, пока не написал, если вы мне поверите). Я провел несколько тестов скорости в больших и малых диапазонах дат, и они, похоже, били друг друга так же часто, поэтому я называю их равными исполнителями. Вот несколько других сравнений:

  • Мы используем функции date() , strtotime() и две функции массива.
  • Drolex использует только три переменные, я использую те же три плюс $x .
  • Поскольку загрузка начальной даты в массив $date не требуется для моей функции, я могу объявить ее в параметрах функции и зарезервировать строку (аналогично $x ).

** Всего несколько важных заметок:

1- Строки даты ДОЛЖНЫ быть проверены перед подачей на функцию.

2- Вышеуказанная функция может обрабатывать только диапазоны дат перемещения вперед. Если вам нужны диапазоны дат перемещения назад, просто измените порядок дат в вызове функции и добавьте минус после $x= . (Довольно скользкий, а?)

 function getDatesFromRange($a,$b,$x=0,$dates=[]){ while(end($dates)!=$b && $x=-array_push($dates,date("Ymd",strtotime("$a +$x day")))); return $dates; } var_export(getDatesFromRange('2010-10-05','2010-10-01')); 

Еще одно расширение / рассмотрение …

Представьте, что у вас есть многокультурная (или неаккуратная) пользовательская база, и ваша функция ДОЛЖНА иметь возможность получать начальные и конечные даты в разных допустимых форматах. И вы должны иметь возможность выводить массив в любом из допустимых форматов? Благодаря небольшой настройке я предоставил решение для этого.

Под «действительным» я имею в виду YYYY-MM-DD , MM/DD/YYY и DD-MM-YYYY , это массово популярные стандарты во всем мире, если нужен другой формат, тогда удобство использования сводилось бы к strtotime Это.

Вот Демо .

Код:

 function getDatesFromRange($a,$b,$format='Ym-d',$dates=[],$x=0){ while(date($format,strtotime(end($dates)))!=date($format,strtotime($b)) && $x=array_push($dates,date($format,strtotime("$a +$x day")))); return $dates; } $formats=array("Computer"=>'Ym-d',"American"=>'m/d/Y','Non-American'=>'dm-Y'); $start='15-02-2017'; // Non-American formatted start date $end='2017-02-27'; // Computer formatted start date foreach($formats as $label=>$format){ echo "<br>$label<br>"; var_export(getDatesFromRange($start,$end,$format)); echo "<br>"; } 

Вывод

 Computer array ( 0 => '2017-02-15', 1 => '2017-02-16', 2 => '2017-02-17', 3 => '2017-02-18', 4 => '2017-02-19', 5 => '2017-02-20', 6 => '2017-02-21', 7 => '2017-02-22', 8 => '2017-02-23', 9 => '2017-02-24', 10 => '2017-02-25', 11 => '2017-02-26', 12 => '2017-02-27', ) American array ( 0 => '02/15/2017', 1 => '02/16/2017', 2 => '02/17/2017', 3 => '02/18/2017', 4 => '02/19/2017', 5 => '02/20/2017', 6 => '02/21/2017', 7 => '02/22/2017', 8 => '02/23/2017', 9 => '02/24/2017', 10 => '02/25/2017', 11 => '02/26/2017', 12 => '02/27/2017', ) Non-American array ( 0 => '15-02-2017', 1 => '16-02-2017', 2 => '17-02-2017', 3 => '18-02-2017', 4 => '19-02-2017', 5 => '20-02-2017', 6 => '21-02-2017', 7 => '22-02-2017', 8 => '23-02-2017', 9 => '24-02-2017', 10 => '25-02-2017', 11 => '26-02-2017', 12 => '27-02-2017', ) 

Теперь некоторые люди не на 100% доверяют strtotime () из-за некоторых ошибок. Я думаю, что прочитал, что он будет испорчен при попытке прыгнуть месяц с високосного дня. Однако, если кто-то не может воспроизвести его, чтобы доказать, что я ошибаюсь, strtotime () никогда не подведет вас, когда вы только увеличиваете на один день.

Чтобы сделать ответ Мостафы полным, это, безусловно, самый простой и эффективный способ сделать это:

 function getDatesFromRange($start_date, $end_date, $date_format = 'Ym-d') { $dates_array = array(); for ($x = strtotime($start_date); $x <= strtotime($end_date); $x += 86400) { array_push($dates_array, date($date_format, $x)); } return $dates_array; } // see the dates in the array print_r( getDatesFromRange('2017-02-09', '2017-02-19') ); 

Вы даже можете изменить формат выходной даты по умолчанию, если вы добавите третий параметр при вызове функции, иначе он будет использовать формат по умолчанию, который был установлен как «Ym-d».

Я надеюсь, что это помогает 🙂

 function getWeekdayDatesFrom($format, $start_date_epoch, $end_date_epoch, $range) { $dates_arr = array(); if( ! $range) { $range = round(abs($start_date_epoch-$end_date_epoch)/86400) + 1; } else { $range = $range + 1; //end date inclusive } $current_date_epoch = $start_date_epoch; for($i = 1; $i <= $range; $i+1) { $d = date('N', $current_date_epoch); if($d <= 5) { // not sat or sun $dates_arr[] = "'".date($format, $current_date_epoch)."'"; } $next_day_epoch = strtotime('+'.$i.'day', $start_date_epoch); $i++; $current_date_epoch = $next_day_epoch; } return $dates_arr; } 
 $arr = range(strtotime("2013-12-01"),strtotime("2013-12-31"), "86400"); array_walk_recursive($arr, function(&$element) { $element = date("Ymd", $element); }); print_r ($arr);