Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

reszko

Trabalhando com Horas Úteis

Recommended Posts

Olá.

 

Estou postando pois não consegui achar uma solução. Vejam se podem me ajudar.

 

Tenho um sitema onde pessoas fazem perguntas e estas perguntas tem prazo em horas úteis para serem respondidas. Preciso saber de uma maneira que ao incrementar as horas úteis a partir do momento em que a pergunta foi criada, me retorne a data e hora finais do prazo.

 

Exemplo:

 

Tipo de pergunta tem 4h úteis para ser respondida

 

Foi criada na data: 26/07/2010 17:00

Então, o sistema deverá me informar como prazo final: 27/07/2010 10:00, assim que a pergunta é gravada.

 

Sabendo que as pessoas que respondem as perguntas trabalham 8:30h úteis por dia, das 8h às 18h, já descontando o almoço.

 

Entenderam? Como somar horas úteis a uma data e se a soma extrapolar o final do expediente, a soma vá para o dia seguinte, continuando a contagem no começo do expediente, que será as 8h.

 

Obviamente que não há função pronta em php, mas a minha maior dificuldade é somar as horas úteis a uma data, porém, o final do dia não será 23:59:59, mas sim 18h.

 

 

Obrigado.

Compartilhar este post


Link para o post
Compartilhar em outros sites

bom, fiz um exemplo.

nao calculei finais de semana, somente horas mesmo.

espero que ajude

 

// alteramos o timezone para nao dar um monte de warnings
date_default_timezone_set('America/Sao_Paulo');

/**
* Calculadora tabajara
*
* Exemplo de como fazer calculos somente com
* horas uteis.
*
* @author Hugo Ferreira da Silva
* @link [url="http-~~-//www.hufersil.com.br/"]http-~~-//www.hufersil.com.br/[/url]
*
*/
class CalculadoraTabajara {
// hora de inicio do almoco
static $inicioAlmoco;
// hora de termino do almoco
static $terminoAlmoco;
// hora de inicio do expediente
static $inicioExpediente;
// hora de termino do expediente
static $terminoExpediente;

/**
* Seta os valores padroes
*
* Iremos sempre trabalhar com minutos
*
*/
public static function setDefaults(){
self::$inicioAlmoco = self::hora2min('12:00');
self::$terminoAlmoco = self::hora2min('13:30');
self::$inicioExpediente = self::hora2min('08:00');
self::$terminoExpediente = self::hora2min('18:00');
}

/**
* Converte as horas em minutos
* descartamos os segundos
*
* @param string $strHora String de hora e minutos
* @return int valor da hora em minutos
*/
public static function hora2min($strHora){
$min = 0;
if( preg_match('@^(d{2})[img=http-~~-//forum.imasters.com.br/public/style_emoticons/default/sad.gif]d{2})([img=http-~~-//forum.imasters.com.br/public/style_emoticons/default/sad.gif]d{2}))?@', $strHora, $reg) ){
$min = $reg[1] * 60 + $reg[2];
}

return $min;
}

/**
* Calcula a data final
*
* @param string $data Data e hora inicial
* @param string $prazo Prazo em horas (exemplo: 05:37)
* @return int Timestamp da data final
*/
public static function calculaPrazoFinal($data, $prazo){
// seta os valores padroes
self::setDefaults();

// verifica a data informada
$res = preg_match('@^((d{2}/d{2}/d{4})|(d{4}-d{2}-d{2})) (d{2})[img=http-~~-//forum.imasters.com.br/public/style_emoticons/default/sad.gif]d{2})(:d{2})?$@', $data, $reg);
// se nao esta no padrao
if( $res == false ){
throw new Exception('Formato de data invalida');
}

// se for data no formato com barras - 25/07/2010
if( !empty($reg[2]) ){
$arr = explode('/', $reg[2]);
$data= mktime(0, 0, 0, $arr[1], $arr[0], $arr[2]);

// se for data no formato do banco - 2010-07-25
} else {
$arr = explode('-', $reg[3]);
$data= mktime(0, 0, 0, $arr[1], $arr[2], $arr[0]);
}

// valor de um dia em segundos
$day = 3600 * 24;

// calcula o prazo em minutos
$prazotime = self::hora2min($prazo);
// hora informada na data inicial em minutos
$hora = self::hora2min($reg[4] . ':' . $reg[5]);

// enquanto houver prazo
while( $prazotime > 0 ){
// incrementa a hora
$hora++;
// decrementa o prazo
$prazotime --;

// se a hora for maior que o expediente
if( $hora > self::$terminoExpediente ){
// adiciona um dia
$data += $day;
// volta para o inicio do expediente
$hora = self::$inicioExpediente + 1;

// se a hora for maior que o inicio do almoco e menor que o termino do almoco
} else if( $hora > self::$inicioAlmoco && $hora < self::$terminoAlmoco ){
// coloca para depois do almoco
$hora = self::$terminoAlmoco + 1;
}

}

// adiciona a hora encontrada (em segundos) na data final
$data += $hora * 60;

// retorna o timestamp da data
return $data;
}
}

////////////////////////////////////////////////////////
// usando a classe
////////////////////////////////////////////////////////

// data inicial
$dataHoraInicio = '25/06/2010 17:32'; // tambem pode ser em 2010-06-25 13:32:45
// prazo
$prazo = '04:00';

// timestamp encontrado
$time = CalculadoraTabajara::calculaPrazoFinal($dataHoraInicio, $prazo);

// exibe a data formatadinha :-)
echo date('d/m/Y H:i', $time);

Compartilhar este post


Link para o post
Compartilhar em outros sites

Desculpa, tinha cometido um erro no código... aqui esta o fixado e funcionando! espero que ajude!!!

 

usei como base as horas que você citou!

<?
$hora = 17;// trocar por date("H"), usei o 17 pelo seu exemplo
$horas_amais = 4;

$inicio = 8;
$termino = 18;
$final = $hora;

for ($i=0; $i!=$horas_amais; $i++) {
	if ($final >= $termino || $final < $inicio)  {
		$final = $inicio;
	} else {
		$final++;
	}
}

echo $final;
?>

Compartilhar este post


Link para o post
Compartilhar em outros sites

Cara, valeu a ajuda. Bem completo e profissional seu código. Vou implementar a parte de feriado e fim de semana e posto os resultados. Andei olhando sua página e gostei do Lumina. Vou aprender a usá-lo e dependendo dos meus resultados, eu faço uma doação a você Imagem Postada .

 

Abraços

 

Valeu a ajuda tabmém AmareshinO.

 

Fábio.

bom, fiz um exemplo.

nao calculei finais de semana, somente horas mesmo.

espero que ajude

 

// alteramos o timezone para nao dar um monte de warnings
date_default_timezone_set('America/Sao_Paulo');

/**
* Calculadora tabajara
*
* Exemplo de como fazer calculos somente com
* horas uteis.
*
* @author Hugo Ferreira da Silva
* @link [url="http-~~-//www.hufersil.com.br/"]http-~~-//www.hufersil.com.br/[/url]
*
*/
class CalculadoraTabajara {
// hora de inicio do almoco
static $inicioAlmoco;
// hora de termino do almoco
static $terminoAlmoco;
// hora de inicio do expediente
static $inicioExpediente;
// hora de termino do expediente
static $terminoExpediente;

/**
* Seta os valores padroes
*
* Iremos sempre trabalhar com minutos
*
*/
public static function setDefaults(){
self::$inicioAlmoco = self::hora2min('12:00');
self::$terminoAlmoco = self::hora2min('13:30');
self::$inicioExpediente = self::hora2min('08:00');
self::$terminoExpediente = self::hora2min('18:00');
}

/**
* Converte as horas em minutos
* descartamos os segundos
*
* @param string $strHora String de hora e minutos
* @return int valor da hora em minutos
*/
public static function hora2min($strHora){
$min = 0;
if( preg_match('@^(d{2})[img=http-~~-//forum.imasters.com.br/public/style_emoticons/default/sad.gif]d{2})([img=http-~~-//forum.imasters.com.br/public/style_emoticons/default/sad.gif]d{2}))?@', $strHora, $reg) ){
$min = $reg[1] * 60 + $reg[2];
}

return $min;
}

/**
* Calcula a data final
*
* @param string $data Data e hora inicial
* @param string $prazo Prazo em horas (exemplo: 05:37)
* @return int Timestamp da data final
*/
public static function calculaPrazoFinal($data, $prazo){
// seta os valores padroes
self::setDefaults();

// verifica a data informada
$res = preg_match('@^((d{2}/d{2}/d{4})|(d{4}-d{2}-d{2})) (d{2})[img=http-~~-//forum.imasters.com.br/public/style_emoticons/default/sad.gif]d{2})(:d{2})?$@', $data, $reg);
// se nao esta no padrao
if( $res == false ){
throw new Exception('Formato de data invalida');
}

// se for data no formato com barras - 25/07/2010
if( !empty($reg[2]) ){
$arr = explode('/', $reg[2]);
$data= mktime(0, 0, 0, $arr[1], $arr[0], $arr[2]);

// se for data no formato do banco - 2010-07-25
} else {
$arr = explode('-', $reg[3]);
$data= mktime(0, 0, 0, $arr[1], $arr[2], $arr[0]);
}

// valor de um dia em segundos
$day = 3600 * 24;

// calcula o prazo em minutos
$prazotime = self::hora2min($prazo);
// hora informada na data inicial em minutos
$hora = self::hora2min($reg[4] . ':' . $reg[5]);

// enquanto houver prazo
while( $prazotime > 0 ){
// incrementa a hora
$hora++;
// decrementa o prazo
$prazotime --;

// se a hora for maior que o expediente
if( $hora > self::$terminoExpediente ){
// adiciona um dia
$data += $day;
// volta para o inicio do expediente
$hora = self::$inicioExpediente + 1;

// se a hora for maior que o inicio do almoco e menor que o termino do almoco
} else if( $hora > self::$inicioAlmoco && $hora < self::$terminoAlmoco ){
// coloca para depois do almoco
$hora = self::$terminoAlmoco + 1;
}

}

// adiciona a hora encontrada (em segundos) na data final
$data += $hora * 60;

// retorna o timestamp da data
return $data;
}
}

////////////////////////////////////////////////////////
// usando a classe
////////////////////////////////////////////////////////

// data inicial
$dataHoraInicio = '25/06/2010 17:32'; // tambem pode ser em 2010-06-25 13:32:45
// prazo
$prazo = '04:00';

// timestamp encontrado
$time = CalculadoraTabajara::calculaPrazoFinal($dataHoraInicio, $prazo);

// exibe a data formatadinha :-)
echo date('d/m/Y H:i', $time);

Compartilhar este post


Link para o post
Compartilhar em outros sites

heheheh que isso!!!

 

 

kra, o dia que eu descobri o lumine... sabe quando falam que aparece a luz no fim do tunel???? entao... pra mim implodiram o tunel e apareceu luz nele todo!!!! uAHuHAuhAUhUAhuAa

 

 

mas ultimamente eu uso o Doctrine... to axando mais simples o code... a unica coisa ruim eh fazer join pelo doctrine Oo meu deus!

 

 

hhehehehe

abraços!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Esse gosta de declarar tudo estático rs.

 

kkkk Imagem Postada

 

na verdade não, mas como fazer uma função usando global para pegar os valores padrões de intervalos (almoço, expediente...) ficaria um tanto "ruim" e como a finalidade desta é só calcular uma data final, preferi fazer uma classe onde os elementos são estáticos mesmo. Fica mais organizado e não precisa ficar criando instâncias.

 

@braços

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.