Función para el Cálculo de Días Laborables en Transact-SQL


Escenario

Para análisis estadísticos es necesario implementar en T-SQL de MS SQL 2000 una función para el cálculo de días laborables entre dos fechas.

Se consideran días Laborables de Lunes a Viernes (de ahora en adelante DIA.LAB) y Fin de Semana Sábado y Domingo (de ahora en adelante FinDe)

Procedimiento

Definimos una función en T-SQL para contabilizar los días laborables atendiendo a los siguientes casos:

  1. Acceder al servidor MS SQL 2000 con permisos necesarios al menos para ejecutar CREATE FUNCTION
  2. Comprobamos que el primer día de la semana es lunes, para ello ejecutamos select @@DATEFIRST el valor debe ser 1
  3. Definimos una función atendiendo a los siguientes casos:
    • Fecha Inicio y Fecha Fin en FinDe
    • Fecha Inicio DIA.LAB y Fecha Fin FinDe
    • Fecha Inicio FinDe y Fecha Fin en FinDe
    • Fecha Inicio y Fecha Fin en DIA.LAB

Utilizamos el siguiente código

CREATE function fBusinessDays (@start datetime, @end datetime)
returns int
as
begin
/*
Descripción:
    Función diseñada para calcular los días LABORABLES entre 2 fechas
*/

DECLARE @wks as int, @LabDays as int — Cálculo de Semanas

/*

Primero calculamos las semanas entre 2 fechas atendiendo a los siguientes casos:

  • F.Inicio en FinDe y F.Fin DIA.LAB -> Convertimos F.Inicio en DIA.LAB sumando 2 días y calculando el número de semanas
  • F.Inicio en DIA.LAB y F.Fin en FinDe -> Convertimos F.Fin en DIA.LAB restando 2 días y calculamos el número de semanas
  • F.Inicio y Fin en Find -> Convertimos F.Inicio y F.Fin en DIA.LAB restando 2 días y calculamos el número de semanas
  • Cualquier otro caso calculamos el número de semanas entre las fechas

*/

    SET @wks = CASE
            WHEN datepart( dw, @start) in (6,7) AND datepart( dw, @end)<6 THEN datediff( week, @start+2, @end)
            WHEN datepart( dw, @start) < 6 AND datepart( dw, @end) in (6,7) THEN datediff( week, @start, @end-2)
            WHEN datepart( dw, @start) in (6,7) AND datepart( dw, @end) in (6,7) THEN datediff( week, @start-2, @end-2)
            ELSE
                datediff( week, @start, @end)
        END

/*

Primero calculamos el número de días DIA.LAB en función de los siguientes casos:

  • F.Inicio en FinDe y F.Fin DIA.LAB -> Total de semanas calculada * 5 + la distancia entre el lunes y F.Fin
  • F.Inicio en DIA.LAB y F.Fin en FinDe -> Total de semanas calculada * 5 + la distancia entre el sábado y F.Inicio
  • F.Inicio y Fin en Find -> Total semanas calculadas * 5 días
  • Cualquier otro caso calculamos el número de semanas entre las fechas

*/

 

    SET @LabDays =
        CASE
            WHEN datepart( dw, @start) in (6,7) AND datepart( dw, @end) in (6,7) THEN @wks*5
            WHEN datepart( dw, @start) in(6,7) AND datepart( dw, @end) < 6  THEN @wks*5 + datepart( dw, @end)
            WHEN datepart( dw, @start) < 6 AND datepart( dw, @end) in (6,7) THEN @wks*5 + (6 – datepart( dw, @start))
            ELSE
                datediff( dd, @start, @end) – @wks*2 + 1
        END

    return( @LabDays)
end

Enlaces de Interés

Para consultar el manejo del lenguaje consultar Transact-SQL Reference

About these ads

5 pensamientos en “Función para el Cálculo de Días Laborables en Transact-SQL

  1. Lo hice algo parecido…

    set datefirst 7

    declare @ini date
    declare @fin date

    set @ini = ’2011-01-30′
    set @fin = ’2011-02-12′

    select
    [Días totales] = datediff ( day, @ini, @fin ) + 1,
    [Días laborales] =
    ( datediff ( week, dateadd ( day, – datepart ( weekday, @ini ) + 1, @ini ), dateadd ( day, 7 – datepart ( weekday, @fin ), @fin ) ) + 1 ) * 5 -
    ( case when datepart ( weekday, @ini ) = 1 then 0 else datepart ( weekday, @ini ) – 2 end +
    case when datepart ( weekday, @fin ) = 7 then 0 else 6 – datepart ( weekday, @fin ) end
    )

    ¡Saludos!

  2. No se si he entendido bien la ultima funcion pero creo que quedaria mas generica agregando el @@DATEFIRST para la resta de manera que no dependa de que este valor sea = 7. Espero sirva

    declare @ini date
    declare @fin date

    set @ini = ’2011-01-30′
    set @fin = ’2011-02-12′

    select
    [Días totales] = datediff ( day, @ini, @fin ) +1,
    [Días laborales] =
    ( datediff ( week, dateadd ( day, – datepart ( weekday, @ini ) + 1, @ini ), dateadd ( day, @@DATEFIRST – datepart ( weekday, @fin ), @fin ) ) + 1 ) * 5 -
    ( case when datepart ( weekday, @ini ) = 1 then 0 else datepart ( weekday, @ini ) – 2 end +
    case when datepart ( weekday, @fin ) = 7 then 0 else 6 – datepart ( weekday, @fin ) end
    )

  3. “Función para el Cálculo de Días Laborables en Transact-SQL Blog Profesional de Fco.
    J. Pérez” was quite enjoyable and instructive! Within the present
    day universe that is tough to execute. Regards, Amee

Deja un comentario

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s