Fórum Diferença entre 2 TIMESTAMPS, somente horas úteis #54536
03/01/2006
0
Ex: A primeira hora é 17:00 de hoje e a segunda é 10:00 do dia seguinte. Numa diferença normal, seriam 17 horas, mas nesse caso o período útil seria das 09:00 às 18:00, ou seja, seriam, na verdade, 2 horas. Isso tb vale para as 24h de sábados, domingos e feriados.
Alguém tem uma sugestão de como posso montar isso numa SP no Firebird 1.5?
Gandalf.nho
Curtir tópico
+ 0Posts
03/01/2006
Edilcimar
Gostei + 0
03/01/2006
Gandalf.nho
Gostei + 0
03/01/2006
Edilcimar
Pela conta normal realmente são 17 horas usando TIMESTAMP(não tinha reparado, li time), mas de onde aparece este 09:00 as 18:00 que dá 2 horas? Se quiser considerar este período como a jornada de trabalho, então como é que ficam as outras 15 horas trabalhadas? Foram em vão?
Pois neste caso você considera das 17 as 18 (1 hora) e depois no outro dia das 9 as 10 (1 hora), agora se o problema for em digitar hora errada então não permita que a pessoa digite hora entre 18:00 e 09:00!
Gostei + 0
03/01/2006
Gandalf.nho
Gostei + 0
03/01/2006
Afarias
set term ^; create procedure tempo_h (di timestamp, df timestamp) returns (r integer) as begin r = 0; while (di<df) do begin di = di + 0.041667; /* aprox. 1 hora */ if ((not extract(weekday from di) in (0,6)) and (cast(di as time) between ´09:00´ and ´18:00´)) then r = r+1; end suspend; end^ create procedure tempo_m (di timestamp, df timestamp) returns (r integer) as begin r = 0; while (di<df) do begin di = di + 0.000695; /* aprox. 1 min */ if ((not extract(weekday from di) in (0,6)) and (cast(di as time) between ´09:00´ and ´18:00´)) then r = r+1; end suspend; end^
os procedimentos são ´selecionáveis´ ... mas poderiam ser ´executáveis´ -- tanto faz...
T+
Gostei + 0
03/01/2006
Vinicius2k
Um exemplo seria o código abaixo, mas ainda podem existir ´n´ outras variantes como, por exemplo se finais de semana são válidos ou não.
Eu utilizo algorítimos semelhantes para cálculo de tempo em produção e, no meu caso, existe ainda a possibilidade de existirem paradas de produção. Esta(s) parada(s) geram dois ou mais registros de ´inicio´ e ´final´, obrigando a efetuar a agregação.
Além disto, este código deve poder ser melhorado. :)
Considerando uma tabela:
create table horario ( inicial timestamp, final timestamp);
A procedure seria:
create procedure tempoutil returns ( inicial timestamp, final timestamp, horas_uteis double precision) as declare variable util_i time; declare variable util_f time; declare variable dias integer; begin /* período útil */ util_i = ´09:00:00´; util_f = ´18:00:00´; for select inicial, final from horario into :inicial, :final do begin /* verifica se "inicial" e "final" estão dentro do período útil */ if ((cast(inicial as time) >= cast(util_i as time)) and (cast(final as time) <= cast(util_f as time))) then begin /* verifica se "inicial" e "final" estão dentro do mesmo dia */ if (cast(inicial as date) = cast(final as date)) then begin /* se sim, horas_uteis recebe apenas "final" - "inicial" */ horas_uteis = (cast(final as time) - cast(inicial as time)) / 3600; end else begin /* se não... */ /* "horas_uteis" recebe a diferença entre o término do período útil e "inicial" */ horas_uteis = (cast(util_f as time) - cast(inicial as time)) / 3600; /* "horas_uteis" agrega a diferença entre "final" e inicio do período útil*/ horas_uteis = horas_uteis + (cast(final as time) - cast(util_i as time)) / 3600; /* verifica a diferença em dias. se maior que 1, horas_uteis agrega ainda a (qtd de dias - 1) x qtd de horas úteis em um dia */ dias = cast(final as date) - cast(inicial as date); if (dias > 1 ) then begin horas_uteis = horas_uteis + (dias - 1) * ((cast(util_f as time) - cast(util_i as time)) / 3600); end end end suspend; end end
T+
Gostei + 0
04/01/2006
Gandalf.nho
Gostei + 0
04/01/2006
Gandalf.nho
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)