Calcular dias úteis entre datas

Bom dia.

Use o sc_date do SC e com a data final, use o date(‘w’) pra checar qual é o dia da semana. Daí é só usar o sc_date novamente pra adicionar 1 ou 2 dias.

Kleyber,

Não sei como verificar usando o sc_date do SC, sou iniciando em SC, como verifico se é sabado, domingo ou feriado…??? poderia montar uma condições onde tivesse os três elementos, inclusive os feriados que constam da função que passei? Desde já agradeço.

Gilson,

Eu sei muito bem como é isso. Então aqui vão algumas dicas:

1 - Leia bem o Webhelp que tem no teu SC e se não conseguires, tem Webhelp online, pra ver a questão do SC_DATE: http://www.scriptcase.com.br/docs/pt_br/manual_mp.htm#macros-scriptcase/macros-scriptcase

2 - A função date(‘w’) é uma função do PHP que retorna um número informando a que dia da semana se refere. Então 0 - Domingo, 1 - Segunda… e por aí vai. Dá uma olhada no Google sobre essa função. Se não tiveres um certo conhecimento de PHP procure pelas funções e vais descobrindo. Estou sem tempo no momento e se algum dos colegas puder criar um exemplo, seria bom. Senão assim que tiver um tempinho monto um exemplo pra você.

3 - Assista os videos do Scriptcase que existem no site da Netmake. Vai te ajudar bastante.

Kleyber,

Obrigado pela atenção tenho estudado muito sobre o SC, mas quando passamos a desenvolver fica dificil pela falta de conhecimento de PHP e SC.
Sou iniciante mas gosto de estudar. Tentei várias vezes antes de postar… Vou tentar novamente para ver se consigo. Obrigado.

Gilson,

Assim que chegar em casa eu vejo se consigo montar um exemplo do que tu precisas e posto aqui.

Kleyber,

Fico muito grato pela ajuda… fico aguardando.

<?php //CALCULANDO DIAS NORMAIS /*Abaixo vamos calcular a diferença entre duas datas. Fazemos uma reversão da maior sobre a menor para não termos um resultado negativo. */ function CalculaDias($xDataInicial, $xDataFinal){ $time1 = dataToTimestamp($xDataInicial); $time2 = dataToTimestamp($xDataFinal); $tMaior = $time1>$time2 ? $time1 : $time2; $tMenor = $time1<$time2 ? $time1 : $time2; $diff = $tMaior-$tMenor; $numDias = $diff/86400; //86400 é o número de segundos que 1 dia possui $numDias = $numDias +1;//ATENÇÃO NESSA PARTE - FOI ACRESCENTADO PORQUE PRECISO CONTAR COM O DIA ESCOLHIDO, LOGO SEM ISSO PEGA ENTRE AS DATAS DESCARTANDO O DIA INICIAL. return $numDias; } //LISTA DE FERIADOS NO ANO /*Abaixo criamos um array para registrar todos os feriados NACIONAIS existentes durante o ano.*/ function Feriados($ano,$posicao){ $dia = 86400; $datas = array(); $datas['pascoa'] = easter_date($ano); $datas['sexta_santa'] = $datas['pascoa'] - (2 * $dia); $datas['carnaval'] = $datas['pascoa'] - (47 * $dia); $datas['corpus_cristi'] = $datas['pascoa'] + (60 * $dia); $feriados = array ( '01/01', '02/02', // Navegantes date('d/m',$datas['carnaval']), date('d/m',$datas['sexta_santa']), date('d/m',$datas['pascoa']), '21/04', '01/05', date('d/m',$datas['corpus_cristi']), '20/09', // Revolução Farroupilha \m/ '12/10', '02/11', '15/11', '25/12', ); return $feriados[$posicao]."/".$ano; } //FORMATA COMO TIMESTAMP /*Esta função é bem simples, e foi criada somente para nos ajudar a formatar a data já em formato TimeStamp facilitando nossa soma de dias para uma data qualquer.*/ function dataToTimestamp($data){ $ano = substr($data, 6,4); $mes = substr($data, 3,2); $dia = substr($data, 0,2); return mktime(0, 0, 0, $mes, $dia, $ano); } //SOMA 01 DIA function Soma1dia($data){ $ano = substr($data, 6,4); $mes = substr($data, 3,2); $dia = substr($data, 0,2); return date("d/m/Y", mktime(0, 0, 0, $mes, $dia+1, $ano)); } //CALCULA DIAS UTEIS /*É nesta função que faremos o calculo. Abaixo podemos ver que faremos o cálculo normal de dias ($calculoDias), após este cálculo, faremos a comparação de dia a dia, verificando se este dia é um sábado, domingo ou feriado e em qualquer destas condições iremos incrementar 1*/ function DiasUteis($yDataInicial,$yDataFinal){ $diaFDS = 0; //dias não úteis(Sábado=6 Domingo=0) $calculoDias = CalculaDias($yDataInicial, $yDataFinal); //número de dias entre a data inicial e a final $diasUteis = 0; while($yDataInicial!=$yDataFinal){ $diaSemana = date("w", dataToTimestamp($yDataInicial)); if($diaSemana==0 || $diaSemana==6){ //se SABADO OU DOMINGO, SOMA 01 $diaFDS++; }else{ //senão vemos se este dia é FERIADO for($i=0; $i<=12; $i++){ if($yDataInicial==Feriados(date("Y"),$i)){ $diaFDS++; } } } $yDataInicial = Soma1dia($yDataInicial); //dia + 1 } return $calculoDias - $diaFDS; } ?>

Show, Jean. Eu não faria melhor.

E ainda fala que não sabe programar nos webnar… kkkkk
Parabéns Jean.

kkkkkkkkkkk

Muito obrigado ao senhores Kleyber e Jean pelas valiosas ajudas e pelas funções…

Encontre também na net outra que estar dando certo, vou deixar aqui para os demais usuários do forum:

<?php

// Define o formato de saída da data
define('FR_DATA', 'd/m/Y');

$dtfinal = '09/02/2016';

// Teste

echo "O próximo dia util é : ", proDiaUtil($dtfinal); 

/*
 * proDiaUtil()
 * Retorna o próximo dia útil em relação a data.
 *
 * @data   -> Variável que recebe a data. 
 * 			Formato: DD/MM/AAAA
 */
function proDiaUtil($data)
{
	// Separa a data
	$dt = explode('/', $data);
	$dia = $dt[0];
	$mes = $dt[1];
	$ano = $dt[2];
	/*
	
	(1) Pega uma data de referência (variável), compara com o datas definidas pelo sistema (feriados e finais de semana) 
		e retorna a próxima data um dia útil
	(2) As datas do sistema são: [1] sábados; [2] domingos; [3] feriados fixos; [4] feriados veriáveis; [5] dias opcionais (ex: quarta de cinza)
	(3) Retorno o próximo/imediato dia útil.
	
	*/
	
	// 1 - verifica se a data referente é um final de semana (sábado ou domingo); 
	// se sábado acrescenta mais 1 dia e faz nova verificação
	// se domingo acrescenta mais 1 dia e faz nova verificação
	$fsem = date('D', mktime(0,0,0,$mes,$dia,$ano));
	$i = 1;
	switch($fsem)
	{
		case 'Sat': 
			return proDiaUtil(date(FR_DATA, mktime(0,0,0,$mes,$dia+$i,$ano))); 
		break;
		
		case 'Sun':
			return proDiaUtil(date(FR_DATA, mktime(0,0,0,$mes,$dia+$i,$ano)));
		break;
		
		default:
		    // 2 - verifica se a data referente é um feriado
			if(in_array($data, Feriados($ano))== true)
			{
				return proDiaUtil(date(FR_DATA, mktime(0,0,0,$mes,$dia+$i,$ano)));
			}
			else
			{
				// Retorna o dia útil
				return $data;
			}
		break;
	}		
}

/*
 * Feriados()
 * Gera um array com as datas dos feriados com referência no ano da data pesquisada.
 *
 * @ano   -> Variável que recebe o ano base para o cálculo;
 */
function Feriados($ano)
{	
	$feriados = array
	(
	  // Armazena feriados fíxos
	  
	  //Janeiro
	  date(FR_DATA, mktime(0,0,0,'01','01',$ano)), // 01/01 Ano novo
	  date(FR_DATA, mktime(0,0,0,'01','02',$ano)), //  Recesso
	  date(FR_DATA, mktime(0,0,0,'01','03',$ano)), //  Recesso
	  date(FR_DATA, mktime(0,0,0,'01','04',$ano)), //  Recesso
	  date(FR_DATA, mktime(0,0,0,'01','05',$ano)), //  Recesso
	  date(FR_DATA, mktime(0,0,0,'01','06',$ano)), //  Recesso
	  
	   //Março
	  date(FR_DATA, mktime(0,0,0,'03','19',$ano)), //  Dia de São José
	  
	   //Abril  
	  date(FR_DATA, mktime(0,0,0,'04','21',$ano)), // 21/04 Tiradentes
	  
	   //Maio
	  date(FR_DATA, mktime(0,0,0,'05','01',$ano)), // 01/05 Dia do trabalho
	  
	   //Junho
	  date(FR_DATA, mktime(0,0,0,'06','24',$ano)), //  São João
	  
	  //Julho
	  date(FR_DATA, mktime(0,0,0,'07','15',$ano)), //  N. Sa. Perpétuo Socorro
	  
	  //Setembro
	  date(FR_DATA, mktime(0,0,0,'09','07',$ano)), // 07/09 Independencia
	  date(FR_DATA, mktime(0,0,0,'09','28',$ano)), // Dia do Municipio de Acopiara
	  
	  //Outubro
	  date(FR_DATA, mktime(0,0,0,'10','04',$ano)), // São Francisco
	  date(FR_DATA, mktime(0,0,0,'10','12',$ano)), // 12/10 N. Senhora Aparecida
	  
	  
	  //Novembro
	  date(FR_DATA, mktime(0,0,0,'11','02',$ano)), // 02/11 Finados	  
	  date(FR_DATA, mktime(0,0,0,'11','15',$ano)), // 15/11 Proclamação
	  
	  //Dezembro
	  date(FR_DATA, mktime(0,0,0,'12','20',$ano)), //  Recesso
	  date(FR_DATA, mktime(0,0,0,'12','21',$ano)), //  Recesso
	  date(FR_DATA, mktime(0,0,0,'12','22',$ano)), //  Recesso
	  date(FR_DATA, mktime(0,0,0,'12','23',$ano)), //  Recesso
	  date(FR_DATA, mktime(0,0,0,'12','24',$ano)), // 24/12 Véspera de Natal
	  date(FR_DATA, mktime(0,0,0,'12','25',$ano)), // 25/12 Natal
	  date(FR_DATA, mktime(0,0,0,'12','26',$ano)), //  Recesso
	  date(FR_DATA, mktime(0,0,0,'12','27',$ano)), //  Recesso
	  date(FR_DATA, mktime(0,0,0,'12','28',$ano)), //  Recesso
	  date(FR_DATA, mktime(0,0,0,'12','29',$ano)), //  Recesso
	  date(FR_DATA, mktime(0,0,0,'12','30',$ano)), //  Recesso	  
	  date(FR_DATA, mktime(0,0,0,'12','31',$ano)), // 31/12 Véspera de Ano novo
	  
	  
	  // Armazena feriados variáveis
	  //flxFeriado($ano, 'pascoa', $r = 1), // Páscoa - Sempre domingo
	  flxFeriado($ano, 'carn_sab', $r = 1), // Carnaval - Sempre sábado
	  flxFeriado($ano, 'carn_dom', $r = 1), // Carnaval - Sempre domingo
	  flxFeriado($ano, 'carn_seg', $r = 1), // Carnaval - Segunda
	  flxFeriado($ano, 'carn_ter', $r = 1), // Carnaval - Terça
	  //strtoupper(flxFeriado($ano, 'carn_qua', $r = 1)), // Carnaval - Quarta de cinza
	  flxFeriado($ano, 'sant_sex', $r = 1), // Sexta Santa
	  flxFeriado($ano, 'corp_chr', $r = 1)  // Corpus Christi
	);
	return $feriados;
}

/*
 * flxFeriado()
 * Calcula os dias de feriados variáveis. Com base na páscoa.
 *
 * @ano   -> Variável que recebe o ano base para o cálculo;
 * @tipo  -> Tipo de dados
 * 			[carn_sab]: Sábado de carnaval;
 * 			[carn_dom]: Domingo de carnaval;
 * 			[carn_seg]: Segunda-feira de carnaval;
 * 			[carn_ter]: Terça-feira de carnaval;
 * 			[carn_qua]: Quarta-feira de carnaval;
 * 			[sant_sex]: Sexta-feira santa;
 * 			[corp_chr]: Corpus Christi;
 */
 
function flxFeriado($ano, $tipo = NULL)
{
	$a=explode("/", calPascoa($ano));
	switch($tipo)
	{
		case 'carn_sab': $d = $a[0]-50; break;
		case 'carn_dom': $d = $a[0]-49; break;
		case 'carn_seg': $d = $a[0]-48; break;
		case 'carn_ter': $d = $a[0]-47; break;
		case 'carn_qua': $d = $a[0]-46; break;
		case 'sant_sex': $d = $a[0]-2; break;
		case 'corp_chr': $d = $a[0]+60; break;
		case NULL: 
		case 'pascoa': $d = $a[0]; break;
	}
	return date(FR_DATA, mktime(0,0,0,$a[1],$d,$a[2])); break;
}

/*
 * calPascoa()
 * Calcula o domingo da pascoa. Base para todos os feriádos móveis.
 *
 * @ano   -> Variável que recebe o ano base para o cálculo ;
 */
 
function calPascoa($ano)
{
	$A = ($ano % 19);
    $B = (int)($ano / 100);
    $C = ($ano % 100);
    $D = (int)($B / 4);
    $E = ($B % 4);
    $F = (int)(($B + 8) / 25);
    $G = (int)(($B - $F + 1) / 3);
    $H = ((19 * $A + $B - $D - $G + 15) % 30);
    $I = (int)($C / 4);
    $K = ($C % 4);
    $L = ((32 + 2 * $E + 2 * $I - $H - $K) % 7);
    $M = (int)(($A + 11 * $H + 22 * $L) / 451);
    $P = (int)(($H + $L - 7 * $M + 114) / 31);
    $Q = (($H + $L - 7 * $M + 114) % 31) + 1;
    return date('d/m/Y', mktime(0,0,0,$P,$Q,$ano));
}

?>

Que bom que resolveu, Gilson. E obrigado por compartilhar o código. Vai ser útil sim.

na verdade sou um exper em pesquisar…
achei o script na net, porém fiz algumas adaptações…

Jean chic.
Só tenho uma observação a fazer.
Tem um bug na sua assinatura onde você fecha a “]” não encontrei onde você abriu a chave.
Ai fiquei sem saber direito sua especialidade.
kkkkkkkkk

Caro [size=1em][font=Verdana]GCONTABIL2015 Todo código compartilhado é válido.
Obrigado por compartilhar.[/font][/size]

Obrigado a todos pela valiosa ajuda.

Acho que isso atende ao que você precisa.
Você pode copiar este código e executá-lo em uma blank para ajustar ao que precisa.

//DATA INICIAL
$data_1=‘2016-02-09’;
//INCREMENTO DE DIAS A DATA INICIAL
$add_dias=80;
//CONTADOR DE FERIADOS
$contador=0;
//ARRAY COM FERIADOS
$feriados_array = array(‘2016-01-01’, ‘2016-02-09’, ‘2016-03-25’, ‘2016-03-27’, ‘2016-04-25’,
‘2016-26-01’, ‘2016-05-26’, ‘2016-06-10’, ‘2016-06-13’);
//TRATAMENTO DA DATA FINAL
$data_2=date_create($data_1);
date_add($data_2,date_interval_create_from_date_string("$add_dias day"));
$data_2=date_format($data_2,“Y-m-d”);

//LAÇO DE REPETIÇÃO DE INCREMENTO E COMPARAÇÃO ENTRE DATAS
while($data_1 < $data_2){

if (in_array($data_1, $feriados_array)) { 
	$contador++;
}
//TRATAMENTO E INCREMENTO DA DATA INICIAL
$data_1=date_create($data_1);
date_add($data_1,date_interval_create_from_date_string("1 day"));
$data_1=date_format($data_1,"Y-m-d");

}
$data_2=date_create($data_2);
date_add($data_2,date_interval_create_from_date_string("-$contador day"));
$data_2=date_format($data_2,“Y-m-d”);

echo ‘DATA DO AGENDAMENTO = ‘.$data_1.’ - ‘.$contador.’ DIA
’;
echo ‘DATA DO AGENDAMENTO = ‘.$data_2.’
’;

encontrei esta rotina que permite retirar apenas os fins e semana:
//get current month for example
$beginday = “2019-10-01”;
$lastday = “2019-10-31”;

$nr_work_days = getWorkingDays($beginday, $lastday);
echo $nr_work_days;

function getWorkingDays($startDate, $endDate)
{
$begin = strtotime($startDate);
$end = strtotime($endDate);
if ($begin > $end) {
echo "startdate is in the future!
";

    return 0;
} else {
    $no_days  = 0;
    $weekends = 0;
    while ($begin <= $end) {
        $no_days++; // no of days in the given interval
        $what_day = date("N", $begin);
        if ($what_day > 5) { // 6 and 7 are weekend days
            $weekends++;
        };
        $begin += 86400; // +1 day
    };
    $working_days = $no_days - $weekends;

    return $working_days;
}

}

1 Curtida

Sou iniciante no Scriptcase, como posso usar essa função dentro do onload, testei no blank e funcionou. dentro do onload da um erro:Parse error: syntax error, unexpected ‘{’ in C:\Program Files\NetMake\v9\wwwroot\scriptcase\app\SISBOB\form_spc_credito\form_spc_credito_apl.php on line 8014

Incluindo dias não úteis e feriados nacionais.