How to create a list of dates of the year in php, skipping the weekends?

7

I need to create a list of dates in PHP, where I will list all dates, from the first day of the year to the last. However, in that list, dates for the weekend (Saturday and Sunday) should be skipped.

Example:

01/02/2016 => Segunda
02/02/2016 => Terça
03/02/2016 => Quarta
04/02/2016 => Quinta
05/02/2016 => Sexta
08/02/2016 => Segunda

Does anyone have any idea how to do this in php?

    
asked by anonymous 04.02.2016 / 13:27

4 answers

8

You can use class DatePeriod to set the desired time period, in the example I used the month of February, to know what days are weekends (Saturday and Sunday) the English gives a help, since both days start with S saturday and sunday), just know if the week day starts with S or not.

$inicio = new DateTime('2016-02-01');
$fim = new DateTime('2016-02-29');

$periodo = new DatePeriod($inicio, new DateInterval('P1D'), $fim);
$validos = [];
foreach($periodo as $item){

    if(substr($item->format("D"), 0, 1) != 'S'){
        $validos[] = $item->format('d/m/Y');
    }
}


echo "<pre>";
print_r($validos);

Saida:

Array
(
    [0] => 01/02/2016
    [1] => 02/02/2016
    [2] => 03/02/2016
    [3] => 04/02/2016
    [4] => 05/02/2016
    [5] => 08/02/2016
    [6] => 09/02/2016
    [7] => 10/02/2016
    [8] => 11/02/2016
    [9] => 12/02/2016
    [10] => 15/02/2016
    [11] => 16/02/2016
    [12] => 17/02/2016
    [13] => 18/02/2016
    [14] => 19/02/2016
    [15] => 22/02/2016
    [16] => 23/02/2016
    [17] => 24/02/2016
    [18] => 25/02/2016
    [19] => 26/02/2016
)
    
04.02.2016 / 13:42
2

I have a solution too, and it's almost like the @rray response, but with some variations and explanations about Iterators used.

Come on:

// Defini a data inicial como 01/01 do ano atual

$startDate = DateTime::createFromFormat('m-d', '01-01');

$endDate = clone $startDate;

// Modifico o clone colocando para o ano que vem

$endDate->modify('+1 year');


// Adiciona um intervaldo de 1 em 1 dia

$interval = DateInterval::createFromDateString('+1 day');

// Criamos um objeto DatePeriod, que também é um iterator

$period = new DatePeriod($startDate, $interval, $endDate);

// Passo DatePeriod para argumento de IteratorIterator
// Faço isso pois DatePeriod implementa Traversable, 
// que não é aceita por callbackFilterIterator 
// (que aceita uma implementação de Iterator como parâmetro)
// Então nesse caso, IteratorIterator aceita Traversable. 
// E CallbackFilterIterator aceita Iterator (que é implementado por IteratorIterator)

$iterablePeriod = new IteratorIterator($period);


// Utilizo esse Iterator para filtrar o outro DatePeriod, ignorando sábados e domíngos


$iterator = new CallbackFilterIterator($iterablePeriod, function ($date)
{
    $week = $date->format('w');

    return $week != '0' && $week != '6';
});


// No final posso transformar num 'array' de objetos Datetime

// Or iterate $iterator through foreach     print_r (iterator_to_array ($ iterator));

    
04.02.2016 / 13:44
2

I would do so

<?php
$diasDaSemana = array(
    1=>'Segunda',
    2=>'Terça',
    3=>'Quarta',
    4=>'Quinta',
    5=>'Sexta',
);
$inicio = DateTime::CreateFromFormat("d-m",'01-01');

$fim = clone $inicio;
$fim->modify('+1 year');

$interval = new DateInterval('P1D');
$daterange = new DatePeriod($inicio, $interval ,$fim);
foreach ($daterange as $date){

  if($date->format('w') !=0 && $date->format('w') !=6 ){
    $arrayDatas[] =  $date;
  }

  //ou pra ficar como no seu exemplo
  if($date->format('w') !=0 && $date->format('w') !=6 ){
    $array[$date->format('d-m-Y')] =  $diasDaSemana[$date->format('w')];
  }
}
  echo "<pre>\n";
  var_dump($arrayDatas);
  echo "</pre>\n";

  echo "<pre>\n";
  var_export($array);
  echo "</pre>\n";
    
04.02.2016 / 14:12
2

We already have several answers, but there goes another way, in "compact version":

$year = 2016;

for( $d = mktime( 0, 0, 0, 1, 1, $year ); date( 'Y', $d ) == $year; $d += 86400 )
    date( 'N', $d ) < 6 ? $lista[] = date( 'd/m/Y', $d ) : $d += 86400;

See working at IDEONE .


Operation:

  • $d = mktime( 0, 0, 0, 1, 1, $year ) creates a timestamp of the first day of the year you want

  • date( 'Y', $d ) == $year causes the loop to remain only in the desired year

  • $d += 86400 adds a day to timestamp (86400 = 24 * 60 * 60 seconds).

  • date( 'N', $d ) < 6 checks for working day

  • If it is, $lista[] = date( 'd/m/Y', $d ) adds the date to the list.

  • )
21.02.2016 / 20:31