Leandro Vieira Pinho´s Blog

Just another WordPress weblog

Somando dias utéis a uma data específica com PHP

December 5th, 2006. Published under mysql, php. 14 Comments.

Durante meu trabalho hoje no desenvolvimento de um projeto, precisei somar uma quantidade X de dias úteis a uma data específica. Logo recorri a um grande amigo que sempre me diz se alguém já precisou do mesmo recurso e encontrou/desenvolveu algo a respeito.

Nessa recorrida, encontrei um tópico e um post que me inspirou a criar a seguinte função em PHP:

[UPDATE] Anderson Mello contribui para a solução de bug na função. Grato Anderson. [/UPDATE]

function somar_dias_uteis($str_data,$int_qtd_dias_somar = 7) {

    // Caso seja informado uma data do MySQL do tipo DATETIME - aaaa-mm-dd 00:00:00

    // Transforma para DATE - aaaa-mm-dd

    $str_data = substr($str_data,0,10);

    // Se a data estiver no formato brasileiro: dd/mm/aaaa

    // Converte-a para o padrão americano: aaaa-mm-dd

    if ( preg_match("@/@",$str_data) == 1 ) {

        $str_data = implode("-", array_reverse(explode("/",$str_data)));

    }

    $array_data = explode('-', $str_data);

    $count_days = 0;

    $int_qtd_dias_uteis = 0;

    while ( $int_qtd_dias_uteis < $int_qtd_dias_somar ) {

        $count_days++;

                if ( ( $dias_da_semana = gmdate('w', strtotime('+'.$count_days.' day', mktime(0, 0, 0, $array_data[1], $array_data[2], $array_data[0]))) ) != '0' && $dias_da_semana != '6' ) {

            $int_qtd_dias_uteis++;

        }

    }

    return gmdate('d/m/Y',strtotime('+'.$count_days.' day',strtotime($str_data)));

}

Exemplo de uso:

echo somar_dias_uteis('05/12/2006');

echo somar_dias_uteis('2006-12-01',15);

O que ela faz é pegar a data informada, somar uma quantidade de dias úteis a ela e retornar uma nova data com a soma realizada.

Se você informar à função uma data no formato brasileiro - dd/mm/aaaa - ela irá convertê-la para o padrão americano - aaaa-mm-dd. Esse padrão americano é utilizado pelo MySQL quando você define um campo com o formato DATE. Caso sua data esteja armazenada no formato DATETIME a função irá pegar somente a data e excluir o horário :)

Alguma dúvida? Sugestão? Comente aí!

14 Comments

Rafael Dohms  on December 5th, 2006

Excelente uso da função strtotime() Leandro!
Realmetne uma soma com um conceito de “dias úteis” é algo que falta no PHP.

Parabéns pelo post e pela função!

Abraço

leandro  on December 6th, 2006

Valeu Rafael,

As duas referências que obtive (incluindo a sua) me ajudaram legal no desenvolvimento desta função.

Obrigado pelo parabéns.

Outro abraço.

Allan Patrick  on February 5th, 2007

Leandro,

Ao executar o seguinte:
echo somar_dias_uteis(’2007-02-16′,3);

A função retorna: 19/02/2007 (está somando sábado e domingo)

porém deveria retornar: 21/02/2007.

Você sabe o motivo?

De qualquer forma, parabéns pela iniciativa de publicar o código

leandro  on February 6th, 2007

Olá Allan,

Realmente cara, estranho isso. Se você utilizar 4, 5, ou em diante funciona normal. Quando sobrar o tempo vou analisar.

Allan Patrick  on February 8th, 2007

Leandro,

Não tive tempo de depurar o código, mas percebi o seguinte:
Ex: echo somar_dias_uteis(’2007-02-16′,4); (Resultado Correto: 22/2/2007)

Se eu executar este código no dia 05/2/2007 - Segunda feira (data no servidor PHP) tenho como resutado a data 20/02/2007 (Errado)

Se eu executar este código no dia 06/2/2007 (Terça) até 09/20007 (Sexta) (data no servidor PHP) tenho como resutado a data 22/02/2007 (Data correta)

Se eu executar este código no dia 10/2/2007 (sábado) ou 11/02/20007 (domingo) (data no servidor PHP) tenho como resutado a data 21/02/2007 (Errado)

Com outras datas, principalmente em janeiro/2007 ocorre este problema.

Espero que isto ajude!

Allan Patrick  on February 8th, 2007

Leandro,

Acho que descobri o Problema. O seu algoritmo está correto, porem para funcionar 100% o fuso horário do computador aonde roda o servidor deve estar setado para GMT - Hora de Greenwich. Se estiver no fuso GMT -3horas Brasília, vai dar diferença.

Se utilizar as funções gmmktime() e gmdate(), ao invés de mktime() e date(), a configuração do fuso horário fica transparente.

Um caso semelhante é relatado no endereço: http://bugs.php.net/461

Espero ter ajudado. Abraço.

Marcele  on June 26th, 2007

Realmente era o que faltava…excelente script, só uma observacao na linha onde tem… $dias_da_semana != ‘6′ ) {

eu alterei para $dias_da_semana != ‘7′ ) {… ai a data deu certo.
tb coloquei assim para calcular a mais por exemplos 5 dias uteis

$hoje=date(’Y-m-d’);
echo “Hoje mais 5 dias —> “.somar_dias_uteis($hoje,5);

é claro que modifiquei o formato do date para y-m-d

abraços!

Paulo Rebelo  on June 29th, 2007

era mesmo o que andava a procura. obrigadão.
melhor ainda seria se considera-se os feriados.

Paulo Rebelo  on July 2nd, 2007

descupa mas não coube tudo de uma vez :)
…………………………………..

while ( $int_qtd_dias_uteis

Paulo Rebelo  on July 2nd, 2007

while ( $int_qtd_dias_uteis

Paulo Rebelo  on July 2nd, 2007

oi
tou com dificuldade de fazer posts.
acrescentei umas coisas a função de modo a ter em conta os feriados
passei um parametro:
function somar_dias_uteis($str_data,$int_qtd_dias_somar = 7,$feriados)

$feriados ,array() k traz o feriados k você definir;

depois criei a variavel:

$day = date(’Y-m-d’,strtotime(’+’.$count_days.’ day’,strtotime($str_data)));

no final acrescentei a condição:

&& !in_array($day,$feriados)

onde é usada a variavel $day

leandro  on July 2nd, 2007

Cara, me encaminhe a adaptação que fez com exemplo de uso, que irei editar o post para adicioná-la com seus créditos.

E-mail: leandro.w3invent [at] gmail [dot] com

Cleison  on January 24th, 2008

Cara estou colocando a data do dia 19/01/2008 e parametrizando para somar 0 (zero) eu seja gostaria de saber se a data do dia 19/01/2008 é final de semana ou não como é um sabado teria que retornar a data do dia 21/01/2008.

Não tens nenhuma função que faça isso.
Verifique se o dia informado é final de semana ou não?

le  on May 20th, 2008

vlw por publicar o código.
tem muita utilidade

muito foda

Leave a Comment