Trabalhando com Feriados e Dias Úteis

Desenvolvi esses métodos, os quais utilizo desde 2007, a pedido no grupo implementei hoje mais dois métodos para calcular dias uteis entres duas datas e calcular uma data final a partir de uma data inicial e dias úteis.
Seguem métodos php que podem ajudar a fazer cálculos com datas e dias úteis e feriados nacionais

Demonstrando:
https://v9.infinitusweb.com.br/forum_sc/teste_feriados/

Download app exemplo acima:
http://bit.ly/2NoCc92

Arquivo diaUtil.php inserido via biblioteca externa:

<?php
function getDiaDaSemana($timestamp)
{ 
	$timestamp = strtotime($timestamp); 
	$date = getdate($timestamp); 
	$diaSemana = $date['weekday']; 
	if(preg_match('/(sunday|domingo)/mi',$diaSemana)) $diaSemana = 'Domingo'; 
	else if(preg_match('/(monday|segunda)/mi',$diaSemana)) $diaSemana = 'Segunda'; 
	else if(preg_match('/(tuesday|terça)/mi',$diaSemana)) $diaSemana = 'Terça'; 
	else if(preg_match('/(wednesday|quarta)/mi',$diaSemana)) $diaSemana = 'Quarta'; 
	else if(preg_match('/(thursday|quinta)/mi',$diaSemana)) $diaSemana = 'Quinta'; 
	else if(preg_match('/(friday|sexta)/mi',$diaSemana)) $diaSemana = 'Sexta'; 
	else if(preg_match('/(saturday|sábado)/mi',$diaSemana)) $diaSemana = 'Sábado'; 
	return $diaSemana; 
}

function vencimento($data,$DIAS_PGTO=0)
{ 
	$data = date('Y-m-d', strtotime($data. '+ '.$DIAS_PGTO.' days')); 
 	if(getDiaDaSemana($data)==("Sábado"))
	{ 
	 	$data = date('Y-m-d', strtotime($data. ' + 2 days')); 
 	}
 	else if(getDiaDaSemana($data)==("Domingo"))
	{ 
		$data = date('Y-m-d', strtotime($data. '+ 1 days')); 
	} 
 	return $data; 
}

function Dia_Util($data,$DIAS_PGTO=0)
{ 
	$feriados=Feriados(date('Y',strtotime($data)));
	$dutil=FALSE;
	while (!$dutil) {
    	$data=vencimento($data,$DIAS_PGTO);
		if (array_value_recursive($data, $feriados) <> NULL)
		{
			$data = date('Y-m-d', strtotime($data. '+ 1 days')); 
			$data=vencimento($data,$DIAS_PGTO);
		}else{
			$dutil=TRUE;	
		}
	} 
 	return $data; 
}


function DataPascoa($Ano)  {
	$Rest =($Ano % 19)+1;
  switch ($Rest) {
    case 1: $Dia = mktime(0,0,0, 4, 14, $Ano); break;
    case 2: $Dia = mktime(0,0,0, 4, 3, $Ano); break;
    case 3: $Dia = mktime(0,0,0, 3, 23, $Ano); break;
    case 4: $Dia = mktime(0,0,0, 4, 11, $Ano); break;
    case 5: $Dia = mktime(0,0,0, 3, 31, $Ano); break;
    case 6: $Dia = mktime(0,0,0, 4, 18, $Ano); break;
    case 7: $Dia = mktime(0,0,0, 4, 8, $Ano); break;
    case 8: $Dia = mktime(0,0,0, 3, 28, $Ano); break;
    case 9: $Dia = mktime(0,0,0, 4, 16, $Ano); break;
    case 10: $Dia = mktime(0,0,0, 4, 5, $Ano); break;
    case 11: $Dia = mktime(0,0,0, 3, 25, $Ano); break;
    case 12: $Dia = mktime(0,0,0, 4, 13, $Ano); break;
    case 13: $Dia = mktime(0,0,0, 4, 2, $Ano); break;
    case 14: $Dia = mktime(0,0,0, 3, 22, $Ano); break;
    case 15: $Dia = mktime(0,0,0, 4, 10, $Ano); break;
    case 16: $Dia = mktime(0,0,0, 3, 30, $Ano); break;
    case 17: $Dia = mktime(0,0,0, 4, 17, $Ano); break;
    case 18: $Dia = mktime(0,0,0, 4, 7, $Ano); break;
    case 19: $Dia = mktime(0,0,0, 3, 27, $Ano); break;
  }
  $Ret = "";
  for ($n=1; $n<=13; $n++) {
    $Dia+=86400;

    if (date('l',$Dia)=="Sunday"){
       	$dd = date('d',$Dia);
		$mm = date('m',$Dia);
        return date('Y-m-d',$Dia);
    }
  }
  return "";
}

Function Feriados($ano)
{
	$feriados[$ano.'-01-01']='Confraternização Universal';
	$feriados[$ano.'-04-21']='Tiradentes';
	$feriados[$ano.'-05-01']='Dia do Trabalho';
	$feriados[$ano.'-09-07']='Proclamação da Independência';
	$feriados[$ano.'-10-12']='Nossa Srª Aparecida';
	$feriados[$ano.'-11-02']='Finados';
	$feriados[$ano.'-11-15']='Proclamação da República';
	$feriados[$ano.'-12-25']='Natal';
	
	$pascoa=DataPascoa($ano);
	
	$feriados[date('Y-m-d', strtotime($pascoa. ' - 48 days'))]='Segunda de Carnaval';
	$feriados[date('Y-m-d', strtotime($pascoa. ' - 47 days'))]='Terça de Carnaval';
	$feriados[date('Y-m-d', strtotime($pascoa. ' - 2 days'))]='Sexta-Feira da Paixão';
	$feriados[$pascoa]='Páscoa';
	$feriados[date('Y-m-d', strtotime($pascoa. ' + 60 days'))]='Corpus Christi';
	
	Return $feriados;
	
}

function array_value_recursive($key, array $arr){
    $val = array();
    array_walk_recursive($arr, function($v, $k) use($key, &$val){
        if($k == $key) array_push($val, $v);
    });
    return count($val) > 1 ? $val : array_pop($val);
}

function  conta_dias_uteis($di, $df) {
	$dias_uteis =0;
	$dc = $di;
	while ($df > $dc) {
	  if ($dc == Dia_Util($dc)) $dias_uteis++;
      $do = new DateTime($dc);
	  $do->add( new DateInterval( "P1D" ) ); 
	  $dc = $do->format( "Y-m-d" ) ;	
	}
	return $dias_uteis;
}
//Aqui aplicando Clean Code
function  calcDataDiaUteis($dataInicial, $diasUteis) {
	$dataCorrente = $dataInicial;
	$i = 0;
	while ($i <= $diasUteis) {
	  if ($dataCorrente == Dia_Util($dataCorrente)) $i++; 	
      $dataObjeto = new DateTime($dataCorrente);
	  $dataObjeto->add( new DateInterval( "P1D" ) ); 
	  $dataCorrente = $i <= $diasUteis ? $dataObjeto->format( "Y-m-d" ) :  $dataCorrente;	
	}
	return $dataCorrente;
}
	
?>

código do exemplo acima:

sc_include_library("prj", "myLibs", "php/DiaUtil.php");

echo  "<pre>".print_r(feriados(2019),true)."</pre>";

echo "<pre> sexta santa '2019-04-19' prox dia util->". Dia_Util('2019-04-19')."  ".getDiaDaSemana(Dia_Util('2019-04-19'))."</pre>"; 

echo "<pre> sabado de carnaval '2019-03-02' prox dia util->". Dia_Util('2019-03-02')."  ".getDiaDaSemana(Dia_Util('2019-03-02'))."</pre>"; 

echo "<pre> confraternização '2019-01-01' prox dia util->". Dia_Util('2019-01-01')."  ".getDiaDaSemana(Dia_Util('2019-01-01'))."</pre>"; 

echo "<pre> um sabado '2019-11-30' prox dia util->". Dia_Util('2019-11-30')."  ".getDiaDaSemana(Dia_Util('2019-11-30'))."</pre>"; 

echo "<pre> dia comum '2019-11-07' prox dia util->". Dia_Util('2019-11-07')."  ".getDiaDaSemana(Dia_Util('2019-11-07'))."</pre>"; 


echo "<pre> conta dias uteis '2019-03-02' a '2019-03-12' possuem ". conta_dias_uteis('2019-03-02','2019-03-12')." dias úteis</pre>";

echo "<pre> calcula data baseado em data inicial + dias úteis. Data Inicial = 2019-03-02 dias úteis= 4  a data final é:". calcDataDiaUteis('2019-03-02',4)."<br> Já serve como teste de mesa para função anterior</pre>";
  

Para implementar feriados locais, basta criar tabela de feriados locais e o retorno ‘mergear’ cin i array dos feriados nacionais.

TAGS: Haroldo, Datas, Feriados, Dias Úteis

10 Curtidas

Bom dia, sou novo no Scriptcase e queria saber se tem como disponibilizar novamente esses links. Queria calcular dias uteis entre duas datas. De já agradeço a atenção.

vou atrás desse código e recrio os links.

https://iwh.tec.br/scriptcase/teste_feriados

sc_include_library("prj", "myLibs", "php/DiaUtil.php");

echo  "<pre>".print_r(feriados(2021),true)."</pre>";



echo "<pre> sexta santa '2021-04-02' prox dia util->". Dia_Util('2021-04-02',1)."  ".getDiaDaSemana(Dia_Util('2021-04-02',1))."</pre>"; 

echo "<pre> sabado de carnaval '2021-02-13' prox dia util->". Dia_Util('2021-02-13')."  ".getDiaDaSemana(Dia_Util('2021-02-13'))."</pre>"; 

echo "<pre> confraternização '2021-01-01' prox dia util->". Dia_Util('2021-01-01',1)."  ".getDiaDaSemana(Dia_Util('2021-01-01',1))."</pre>"; 

echo "<pre> um sabado '2021-01-23' prox dia util->". Dia_Util('2021-01-23',1)."  ".getDiaDaSemana(Dia_Util('2021-01-23',1))."</pre>"; 

echo "<pre> dia comum '2021-01-22' prox dia util->". Dia_Util('2021-01-22',1)."  ".getDiaDaSemana(Dia_Util('2021-01-22',1))."</pre>"; 


echo "<pre> conta dias uteis '2021-03-02' a '2021-03-12' possuem ". conta_dias_uteis('2021-03-02','2021-03-12')." dias úteis</pre>";

echo "<pre> calcula data baseado em data inicial + dias úteis. Data Inicial = 2020-03-02 dias úteis= 4  a data final é:". calcDataDiaUteis('2020-03-02',4)."<br> Já serve como teste de mesa para função anterior</pre>";

  

diaUtil:

<?php
function getDiaDaSemana($timestamp)
{ 
	$timestamp = strtotime($timestamp); 
	$date = getdate($timestamp); 
	$diaSemana = $date['weekday']; 
	if(preg_match('/(sunday|domingo)/mi',$diaSemana)) $diaSemana = 'Domingo'; 
	else if(preg_match('/(monday|segunda)/mi',$diaSemana)) $diaSemana = 'Segunda'; 
	else if(preg_match('/(tuesday|terça)/mi',$diaSemana)) $diaSemana = 'Terça'; 
	else if(preg_match('/(wednesday|quarta)/mi',$diaSemana)) $diaSemana = 'Quarta'; 
	else if(preg_match('/(thursday|quinta)/mi',$diaSemana)) $diaSemana = 'Quinta'; 
	else if(preg_match('/(friday|sexta)/mi',$diaSemana)) $diaSemana = 'Sexta'; 
	else if(preg_match('/(saturday|sábado)/mi',$diaSemana)) $diaSemana = 'Sábado'; 
	return $diaSemana; 
}

function vencimento($data,$DIAS_PGTO=0)
{ 
	$data = date('Y-m-d', strtotime($data. '+ '.$DIAS_PGTO.' days')); 
 	if(getDiaDaSemana($data)==("Sábado"))
	{ 
	 	$data = date('Y-m-d', strtotime($data. ' + 2 days')); 
 	}
 	else if(getDiaDaSemana($data)==("Domingo"))
	{ 
		$data = date('Y-m-d', strtotime($data. '+ 1 days')); 
	} 
 	return $data; 
}

function Dia_Util($data,$DIAS_PGTO=0)
{ 
	$feriados=Feriados(date('Y',strtotime($data)));
	$dutil=FALSE;
	while (!$dutil) {
    	$data=vencimento($data,$DIAS_PGTO);
		if (array_value_recursive($data, $feriados) <> NULL)
		{
			$data = date('Y-m-d', strtotime($data. '+ 1 days')); 
			$data=vencimento($data,$DIAS_PGTO);
		}else{
			$dutil=TRUE;	
		}
	} 
 	return $data; 
}


function DataPascoa($Ano)  {
	$Rest =($Ano % 19)+1;
  switch ($Rest) {
    case 1: $Dia = mktime(0,0,0, 4, 14, $Ano); break;
    case 2: $Dia = mktime(0,0,0, 4, 3, $Ano); break;
    case 3: $Dia = mktime(0,0,0, 3, 23, $Ano); break;
    case 4: $Dia = mktime(0,0,0, 4, 11, $Ano); break;
    case 5: $Dia = mktime(0,0,0, 3, 31, $Ano); break;
    case 6: $Dia = mktime(0,0,0, 4, 18, $Ano); break;
    case 7: $Dia = mktime(0,0,0, 4, 8, $Ano); break;
    case 8: $Dia = mktime(0,0,0, 3, 28, $Ano); break;
    case 9: $Dia = mktime(0,0,0, 4, 16, $Ano); break;
    case 10: $Dia = mktime(0,0,0, 4, 5, $Ano); break;
    case 11: $Dia = mktime(0,0,0, 3, 25, $Ano); break;
    case 12: $Dia = mktime(0,0,0, 4, 13, $Ano); break;
    case 13: $Dia = mktime(0,0,0, 4, 2, $Ano); break;
    case 14: $Dia = mktime(0,0,0, 3, 22, $Ano); break;
    case 15: $Dia = mktime(0,0,0, 4, 10, $Ano); break;
    case 16: $Dia = mktime(0,0,0, 3, 30, $Ano); break;
    case 17: $Dia = mktime(0,0,0, 4, 17, $Ano); break;
    case 18: $Dia = mktime(0,0,0, 4, 7, $Ano); break;
    case 19: $Dia = mktime(0,0,0, 3, 27, $Ano); break;
  }
  $Ret = "";
  for ($n=1; $n<=13; $n++) {
    $Dia+=86400;

    if (date('l',$Dia)=="Sunday"){
       	$dd = date('d',$Dia);
		$mm = date('m',$Dia);
        return date('Y-m-d',$Dia);
    }
  }
  return "";
}

Function Feriados($ano)
{
	$feriados = [];
	$feriados[$ano.'-01-01']='Confraternização Universal';
	$feriados[$ano.'-04-21']='Tiradentes';
	$feriados[$ano.'-05-01']='Dia do Trabalho';
	$feriados[$ano.'-09-07']='Proclamação da Independência';
	$feriados[$ano.'-10-12']='Nossa Srª Aparecida';
	$feriados[$ano.'-11-02']='Finados';
	$feriados[$ano.'-11-15']='Proclamação da República';
	$feriados[$ano.'-12-25']='Natal';
	
	$pascoa=DataPascoa($ano);
	
	$feriados[date('Y-m-d', strtotime($pascoa. ' - 48 days'))]='Segunda de Carnaval';
	$feriados[date('Y-m-d', strtotime($pascoa. ' - 47 days'))]='Terça de Carnaval';
	$feriados[date('Y-m-d', strtotime($pascoa. ' - 2 days'))]='Sexta-Feira da Paixão';
	$feriados[$pascoa]='Páscoa';
	$feriados[date('Y-m-d', strtotime($pascoa. ' + 60 days'))]='Corpus Christi';
	ksort($feriados);
	Return $feriados;
	
}

function array_value_recursive($key, array $arr){
    $val = array();
    array_walk_recursive($arr, function($v, $k) use($key, &$val){
        if($k == $key) array_push($val, $v);
    });
    return count($val) > 1 ? $val : array_pop($val);
}

function  conta_dias_uteis($di, $df) {
	$dias_uteis =0;
	$dc = $di;
	while ($df > $dc) {
	  if ($dc == Dia_Util($dc)) $dias_uteis++;
      $do = new DateTime($dc);
	  $do->add( new DateInterval( "P1D" ) ); 
	  $dc = $do->format( "Y-m-d" ) ;	
	}
	return $dias_uteis;
}

function  calcDataDiaUteis($dataInicial, $diasUteis) {
	$dataCorrente = $dataInicial;
	$i = 0;
	while ($i <= $diasUteis) {
	  if ($dataCorrente == Dia_Util($dataCorrente)) $i++; 	
      $dataObjeto = new DateTime($dataCorrente);
	  $dataObjeto->add( new DateInterval( "P1D" ) ); 
	  $dataCorrente = $i <= $diasUteis ? $dataObjeto->format( "Y-m-d" ) :  $dataCorrente;	
	}
	return $dataCorrente;
}
	
?>

Os métodos estão aí.
Não há necessidade de download.

Link atualizado:

https://iwh.tec.br/scriptcase/teste_feriados/

TAGS: HAROLDO, FERIADOS, DIAS ÚTEIS, DATAS