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

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í!

16 ideias sobre “Somando dias utéis a uma data específica com PHP

  1. 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

  2. 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.

  3. 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

  4. Olá Allan,

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

  5. 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!

  6. 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.

  7. 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!

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

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

    …………………………………..

    while ( $int_qtd_dias_uteis

  10. 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

  11. 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

  12. 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?

  13. olá! Parabens pela função obrigado por publica-lo.. :P

    Precisava disso só para somar um mes a cada loop de um for…
    o problema é que nao consigo achar a funçao adequada sendo queas uncias que encontrei usam o mkTime com a data atual (de hoje) =/ se alguem puder me da uma força aí agradeceria,,, :}

    valeu