PHP

Calculando a diferença de dias úteis entre duas datas utilizando PHP

27/03/2022PHP

Neste artigo vamos ver como calcular a diferença de dias úteis entre duas datas utilizando PHP.

Primeiro vamos ver quais as datas iniciais e finais que vamos trabalhar.

 

$data1 = '2021-01-01';

$data2 = '2021-12-31';

 

Primeiro vamos ver se a data inicial não é maior que a data final.

 

$data_inicial = strtotime($data1);

$data_final   = strtotime($data2);

if ($data_inicial > $data_final) {

    echo "A data inicial é maior que a data final";

}

else {

//Codigo a ser inserido

}

 

Nosso próximo passo é criar um array auxiliar que contenha todos os feriados contidos dentro do intervalo de datas informado. Alguns feriados tem data fixa, e outros tem data variável. Começando pelos feriados de data fixa.

 

$feriados = array();

$ano_inicial = date('Y', $data_inicial); 

$ano_final = date('Y', $data_final);

$ano = $ano_inicial;

for ($x = $ano_inicial; $x <= $ano_final; $x++) {

 

//Feriados com data fixa

$feriados[] = mktime(0, 0, 0, 1,  1,   $ano);

$feriados[] = mktime(0, 0, 0, 4,  21,  $ano);

$feriados[] = mktime(0, 0, 0, 5,  1,   $ano);

$feriados[] = mktime(0, 0, 0, 9,  7,   $ano);

$feriados[] = mktime(0, 0, 0, 10, 12, $ano);

$feriados[] = mktime(0, 0, 0, 11,  2,  $ano);

$feriados[] = mktime(0, 0, 0, 11, 15,  $ano);

$feriados[] = mktime(0, 0, 0, 12, 25,  $ano);

}

 

Neste exemplo foi criado um array auxiliar chamado $feriados. Para adicionar cada data fixa no array, criamos a data utilizando a funçao mktime. Ele cria um timestamp UNIX com a data informada. Seus parâmetros na ordem são hora, minuto, segundo, mês, dia e ano. Para fins didáticos, adicionamos as datas manualmente. Você pode refatorar este código depois e criar uma função para simplicar este processo.

Agora vamos ver os feriados variáveis. Os feriados com data variável dependem da data da páscoa.

 

for ($x = $ano_inicial; $x <= $ano_final; $x++) {

$pascoa = easter_date($ano); 

$dia_pascoa = date('j', $pascoa);

$mes_pascoa = date('n', $pascoa);

$ano_pascoa = date('Y', $pascoa);

 

//Feriados com data variável

$feriados[] = mktime(0, 0, 0, $mes_pascoa, $dia_pascoa - 48,  $ano_pascoa);

$feriados[] = mktime(0, 0, 0, $mes_pascoa, $dia_pascoa - 47,  $ano_pascoa);

$feriados[] = mktime(0, 0, 0, $mes_pascoa, $dia_pascoa - 2 ,  $ano_pascoa);

$feriados[] = mktime(0, 0, 0, $mes_pascoa, $dia_pascoa,  $ano_pascoa);

$feriados[] = mktime(0, 0, 0, $mes_pascoa, $dia_pascoa + 60,  $ano_pascoa);

$ano++;

}

 

Os feriados variáveis são a páscoa, a sexta-feira santa, os dias de carnaval e o Corpus Christi

Agora que temos os feriados, podemos verificar a quantidade de dias uteis entre duas datas. 

 

$fim_semana = 0;

$numero_dias = 0;

$numero_feriados = 0;

while ($data_inicial <= $data_final) {

    $numero_dias++; //Numero de dias do intervalo informado

    if (in_array(date("y-m-d", $data_inicial), $feriados)) {

        $numero_feriados++;

    }

    $dia_semana = date("N", $data_inicial);

    if ($dia_semana > 5) { // 6 e 7 são sábado e domingo

        $fim_semana++;

    };

    $data_inicial += 86400; // +1 dia

 };

 $dias_trabalho = $numero_dias - $fim_semana - $numero_feriados;

 

Para o calculo de dias fizemos um loop usando WHILE entre a data inicial e a data final, e fizemos o incremento da data em 1 dia, somando 86400 segundos a data informada.

Para validar se a data atual é um feriado, utilizamos a função in_array para verificar se aquela data existe no array de feriados.

 

if (in_array(date("y-m-d", $data_inicial), $feriados)) {

    $numero_feriados++;

}

 

Em nosso exemplo não consideremos o sábado e o domingo como dia úteis. Para verificar o dia da semana da data informada, utilizamos a função DATE desta forma:

 

$dia_semana = date("N", $data_inicial);

 

O retorno é um número inteiro. Ele vai retornar 6 para sábado e 7 para domingo.

O código completo fica da seguinte forma:

 

$data1 = '2021-01-01';

$data2 = '2021-12-31';

$data_inicial = strtotime($data1);

$data_final   = strtotime($data2);

if ($data_inicial > $data_final) {

echo "A data inicial é maior que a data final";

return 0;

} else {

$feriados = array();

$ano_inicial = date('Y', $data_inicial); 

$ano_final = date('Y', $data_final);

$ano = $ano_inicial;

for ($x = $ano_inicial; $x <= $ano_final; $x++) {

$pascoa = easter_date($ano); 

$dia_pascoa = date('j', $pascoa);

$mes_pascoa = date('n', $pascoa);

$ano_pascoa = date('Y', $pascoa);

 

//Feriados com data fixa

$feriados[] = mktime(0, 0, 0, 1,  1,   $ano);

$feriados[] = mktime(0, 0, 0, 4,  21,  $ano);

$feriados[] = mktime(0, 0, 0, 5,  1,   $ano);

$feriados[] = mktime(0, 0, 0, 9,  7,   $ano);

$feriados[] = mktime(0, 0, 0, 10,  12, $ano);

$feriados[] = mktime(0, 0, 0, 11,  2,  $ano);

$feriados[] = mktime(0, 0, 0, 11, 15,  $ano);

$feriados[] = mktime(0, 0, 0, 12, 25,  $ano);

 

//Feriados com data variável

$feriados[] = mktime(0, 0, 0, $mes_pascoa, $dia_pascoa - 48,  $ano_pascoa);

$feriados[] = mktime(0, 0, 0, $mes_pascoa, $dia_pascoa - 47,  $ano_pascoa);

$feriados[] = mktime(0, 0, 0, $mes_pascoa, $dia_pascoa - 2 ,  $ano_pascoa);

$feriados[] = mktime(0, 0, 0, $mes_pascoa, $dia_pascoa,  $ano_pascoa);

$feriados[] = mktime(0, 0, 0, $mes_pascoa, $dia_pascoa + 60,  $ano_pascoa);

$ano++;

}

 

$fim_semana = 0;

$numero_dias = 0;

$numero_feriados = 0;

while ($data_inicial <= $data_final) {

$numero_dias++; //Numero de dias do intervalo informado

if (in_array(date("y-m-d", $data_inicial), $feriados)) {

$numero_feriados++;

}

$dia_semana = date("N", $data_inicial);

if ($dia_semana > 5) { // 6 e 7 são sábado e domingo

$fim_semana++;

};

$data_inicial += 86400; // +1 dia

};

$dias_trabalho = $numero_dias - $fim_semana - $numero_feriados;

 

echo $dias_trabalho;

}

Outros conteudos que podem ser de seu interesse

Trabalhando com arrays no PHP
18/04/2021PHP

Trabalhando com arrays no PHP

Aprenda como listar, ordenar e pesquisar arrays com PHP

Saiba mais...
Cotação do dólar com PHP
23/08/2020PHP

Cotação do dólar com PHP

Como obter o valor do dólar através de uma API do Banco Central utilizando PHP

Saiba mais...

Conteúdo sobre banco de dados sem complicação!

MySQL - Referência Rápida

 

SQL Server - Referência Rápida

 

SQL vs Mongo