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

Asked

Viewed 1,750 times

7

I need to create a list of dates in PHP, where I will list all dates, from the first day of the year, until the last. However, in this list, dates referring to the weekend (Saturday and Sunday) must 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?

  • Downvoter, what can be done to improve the question?

4 answers

8


You can use Dateperiod class to assemble the desired time period, in the example I used the month of February, to know which days are weekends (Saturday and Sunday) the English one helps, because both days begin with S(Saturday and Sunday), just know if the weekday 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);

Satida:

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
)
  • Liked the CallbackFilterIterator? I’ve never seen anyone use it!

  • Cool, interesting is that the S has only in Saturday and Sunday. I like things well explained, in your children we start details.

  • @Wallacemaxters I didn’t even remember the day number of the week(0 and 6), I’ve seen someone using :D

  • The only thing I didn’t like is that DatePeriod should implement Iterator. PHP has sinned in this, but I’m glad that it can be corrected. Only my answer was like java (because of the excess of instances).

  • I will mark the answer later, just to see if someone can do it without object orientation, rsrsrsrs.

3

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 on IDEONE.


Functioning:

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

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

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

  • date( 'N', $d ) < 6 check if it’s business day

  • if it’s, $lista[] = date( 'd/m/Y', $d ) adds date to list.

  • if not, $d += 86400 already skips Sunday to "save loop" (could leave without it).

  • Here’s a version in the format [01/01/2016] => Sexta: http://ideone.com/fVDarR

2

I have a solution too, and it’s almost similar to @rray’s response, but with some variations and explanations regarding 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 the foreach print_r(iterator_to_array($iterator));

  • Yeah, I know, that code looked like java.

  • 1

    It’s like Java in here

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

Browser other questions tagged

You are not signed in. Login or sign up in order to post.