Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Bases de datos > Firebird e Interbase
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

 
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 18-02-2014
Avatar de fjcg02
[fjcg02] fjcg02 is offline
Miembro Premium
 
Registrado: dic 2003
Ubicación: Zamudio
Posts: 1.410
Poder: 22
fjcg02 Va camino a la fama
Cálculo de horas laborales

Buenas a todos,
he creado una función que cuenta las horas laborales entre dos fechas, descontando los días del fin de semana y los días festivos.
Para ello, hay que indicarle la fecha y hora de inicio y de fin, las horas de comienzo y fin del horario, y hay que tener en una tabla los festivos (festivos es el nombre de la tabla), para que pueda descontar esos días.
Es útil para por ejemplo medir las horas de cualquier servicio.

Espero que sea útil. Acepto sugerencias para su mejora.

Un saludo

Código SQL [-]
SET TERM ^ ;

CREATE OR ALTER PROCEDURE TIEMPOENTREFECHAS (
    f_inicio timestamp,
    f_fin timestamp,
    horainiciohorario time,
    horafinhorario time)
returns (
    tiempo float)
as
declare variable newf_inicio timestamp;
declare variable newf_fin timestamp;
declare variable sabadosydomingos integer;
declare variable festivos integer;
declare variable winicio timestamp;
declare variable wfin timestamp;
declare variable sabydom integer;
declare variable tiempow float;
declare variable horashorario float;
declare variable tiempodia1 float;
declare variable tiempodia2 float;
declare variable tiempoantesfestivos float;
declare variable tiempoendiasantesfestivos float;
begin
  /* Procedure Text */
    NEWF_INICIO= F_INICIO;
    NEWF_FIN= F_FIN;

   /* Adecuamos la fecha y hora de inicio respecto al fin del horario */
    if (CAST(newf_inicio AS TIME) > horafinhorario ) then
       NEWF_INICIO= CAST(NEWF_INICIO+1 AS DATE) + HORAINICIOHORARIO;

   /* Adecuamos la fecha y hora de inicio respecto al inicio del horario */
    IF (CAST(NEWF_INICIO AS TIME) < horaINICIOhorario ) then
       NEWF_INICIO= CAST(NEWF_INICIO AS DATE) + HORAINICIOHORARIO;
    /* Adecuamos la fecha y hora de inicio respecto a los fines de semana */
    if (EXTRACT(WEEKDAY FROM NEWF_INICIO) = 6) then     /* Sabados*/
       NEWF_INICIO= CAST(NEWF_INICIO+2 AS DATE)+ HORAINICIOHORARIO;
    if (EXTRACT(WEEKDAY FROM NEWF_INICIO) = 0) then /* Domingos*/
       NEWF_INICIO= CAST(NEWF_INICIO+1 AS DATE)+ HORAINICIOHORARIO;

   /* Adecuamos la fecha y hora de fin respecto al fin del horario */
    if (CAST(NEWF_FIN AS TIME)> horafinhorario )  then
       NEWF_FIN= CAST(NEWF_FIN AS DATE)+HORAFINHORARIO;
   /* Adecuamos la fecha y hora de fin respecto al inicio del horario */
    if ( CAST(NEWF_FIN AS TIME) < HORAINICIOhorario ) then
       NEWF_FIN= CAST(NEWF_FIN-1 AS DATE)+HORAFINHORARIO;
    /* Adecuamos la fecha y hora de fin respecto a los fines de semana */
    if (EXTRACT(WEEKDAY FROM NEWF_FIN) = 6) then /* Sabados */
       NEWF_FIN= CAST(NEWF_FIN-1 AS DATE)+ HORAFINHORARIO;
    if (EXTRACT(WEEKDAY FROM NEWF_FIN) = 0) then  /* Domingos*/
       NEWF_FIN= CAST(NEWF_FIN-2 AS DATE)+ HORAFINHORARIO;

     /* Calculamos los dias de fin de semana */
    SABADOSYDOMINGOS =((DATEDIFF(DAY, NEWF_INICIO, NEWF_FIN)+EXTRACT(WEEKDAY FROM NEWF_INICIO) )/7) *2;

    /* Calculamos todos los dias sin fines de semana . Hay que quitarle un día... */
    TIEMPOW = DATEDIFF( DAY, NEWF_INICIO, newf_fin) -1 - SABADOSYDOMINGOS;
    if (TIEMPOW < 0) then
      TIEMPOW=0;
    TIEMPOENDIASANTESFESTIVOS = TIEMPOW;
    TIEMPOANTESFESTIVOS = TIEMPOW * datediff(  MINUTE ,HORAINICIOHORARIO, HORAFINHORARIO) /60.00 + -- Dias transcurrido * horasDia
                          DATEDIFF( minute,  CAST(NEWF_INICIO AS TIME), horafinhorario)/60.00 +  -- horas de primer dia
                          DATEDIFF( minute,  horainiciohorario, CAST(NEWF_FIN AS TIME))/60.00 ; -- horas del ultimo dia
 
    /* Quitamos los festivos pero sin incluir los dias de inicio y fin , que tratamos luego */
    SELECT COUNT(1) FROM festivos 
      WHERE DIA BETWEEN CAST(:NEWF_INICIO AS DATE)+1 AND CAST(:newf_fin AS DATE)-1
      AND EXTRACT(weekday FROM DIA ) NOT IN (0,6) INTO :FESTIVOS;
    TIEMPOW= TIEMPOW - FESTIVOS;

    /* Calculamos el tiempo transcurrido en horas */
    if ( DATEDIFF( DAY, NEWF_INICIO, NEWF_FIN) = 0) then  -- si es el mismo dia, horafin - horainicio
       TIEMPO= DATEDIFF( minute,  CAST(NEWF_INICIO AS TIME), CAST(NEWF_FIN AS TIME)) / 60.00;
    ELSE
        TIEMPO= TIEMPOW * datediff(  MINUTE ,HORAINICIOHORARIO, HORAFINHORARIO) /60.00 + -- Dias transcurridos * horasDia
                          DATEDIFF( minute,  CAST(NEWF_INICIO AS TIME), horafinhorario)/60.00 +  -- horas de primer dia
                          DATEDIFF( minute,  horainiciohorario, CAST(NEWF_FIN AS TIME))/60.00 ; -- horas del ultimo dia

    -- si el primer dia es festivo y no es sabado ni domingo, restamos las horas
    FESTIVOS = 0;
    SELECT COUNT(1) from FESTIVOS
       where dia= cast(:NEWF_INICIO AS DATE)
       AND EXTRACT(weekday FROM DIA ) NOT IN (0,6) INTO :FESTIVOS;
    if (festivos =1) then
       TIEMPO=tiempo - DATEDIFF( minute, CAST(NEWF_INICIO AS TIME), HORAFINHORARIO)/60.00;
    -- si el ultimo día es festivo y no es sabado ni domingo , restamos las horas
    FESTIVOS = 0;
    SELECT COUNT(1) from FESTIVOS
       where dia= cast(:NEWF_FIN AS DATE)
       AND EXTRACT(weekday FROM DIA ) NOT IN (0,6) INTO :FESTIVOS;
    if (festivos =1) then
       TIEMPO=tiempo - DATEDIFF( minute, HORAINICIOHORARIO, CAST(NEWF_FIN AS TIME))/60.00;

    /* Para trazar cuando estoy desarrollando */
    HORASHORARIO = (datediff( MINUTE ,HORAINICIOHORARIO, HORAFINHORARIO))/60.00;
    tiempodia1 = DATEDIFF( minute, CAST(NEWF_INICIO AS TIME), HORAFINHORARIO)/60.00;
    TIEMPODIA2 = DATEDIFF( minute, HORAINICIOHORARIO, CAST(NEWF_FIN AS TIME))/60.00;
    WfIN = NEWF_FIN;
    WINICIO= NEWF_INICIO;
    SABYDOM= SABADOSYDOMINGOS;

TIEMPO= TIEMPO;
    if (TIEMPO < 0 or (TIEMPO IS NULL) ) then
      TIEMPO=0;

  suspend;
end^

SET TERM ; ^

/* Following GRANT statetements are generated automatically */

GRANT SELECT ON FESTIVOS TO PROCEDURE TIEMPOENTREFECHAS;

/* Existing privileges on this procedure */

GRANT EXECUTE ON PROCEDURE TIEMPOENTREFECHAS TO SYSDBA;
__________________
Cuando los grillos cantan, es que es de noche - viejo proverbio chino -
Responder Con Cita
 



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
calculo de diferencia entre dos horas y minutos gonza_619 Varios 1 22-05-2010 20:35:31
Convertir n horas en nnn días y nn horas rretamar Trucos 1 01-08-2008 10:16:34
Calculo de Horas (exactas) Caral Varios 10 09-05-2007 00:28:19
¿Condiciones laborales para el primer contrato de trabajo? bsa_sux Debates 6 28-05-2006 20:19:55
El 1ª de la Promocion de Riegos Laborales Combat-F2D Humor 1 09-05-2004 22:19:48


La franja horaria es GMT +2. Ahora son las 16:12:36.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi