miércoles, 4 de abril de 2012

Funcion para Calcular Horas entre 2 Fechas descartando Fines de Semana SQL Server

En SQL Server existe la funcion dateDiff que devuelve la cantidad de días, horas, semanas, etc. entre dos fechas. Para mas información pueden revisar la documentación de msdn. Esta función es muy útil para realizar cálculos especiales, como antigüedad de registros o el tiempo de vida de alguna persona.

Sin embargo, en casos más especiales, se requeriría calcular el tiempo entre 2 fechas, pero solamente contando los días laborales. Lamentablemente, dateDiff no cuenta con algún parámetro para esto, por lo que hay que aplicar un poco de lógica para conseguirlo.

Basándome en un enlace construí una función que devolviera la cantidad de horas transcurridas entre 2 fechas, descontando fines de semana. Tal vez no sea la mejor manera, o las más optimizada, pero cumple decentemente su objetivo.

SET ANSI_NULLS ON

GO

SET QUOTED_IDENTIFIER ON

GO

ALTER FUNCTION diffHoursWithoutWeekend

(

@fInicio smalldatetime,

@fFin smalldatetime

)

RETURNS int

AS

BEGIN

declare @noHoras int

declare @cuentaLab int

declare @contador int

select @noHoras = dateDiff(hour, @fInicio, @fFin)

select @cuentaLab = 0

select @contador = 0

while(@contador < @noHoras)

begin

declare @diaSemana int

select @diaSemana = datePart(weekDay, dateAdd("hh", @contador, @fInicio))

if (@diaSemana <> 1 and @diaSemana <> 7)

begin

select @cuentaLab = @cuentaLab + 1

end

select @contador = @contador + 1

end

RETURN @cuentaLab

END

GO


Como pueden ver, la función recibe como parámetros de entrada 2 fechas para posteriormente calcular las horas entre ambas. Posteriormente utilizando un ciclo, por cada hora transcurrida determinamos si es fin de semana (por defecto en SQL Server, Domingo es 1, Lunes es 2, etc). En caso de que sea un día laboral, aumentamos el contador de las horas.

La función puede ser fácilmente transformada para que devuelva la cantidad de días. En el enlace indicado viene un ejemplo que lo puede mostrar, así como también una solución propuesta para los casos que se desee descartar días feriados.

Espero les sea útil y cualquier comentario o mejora es bienvenida.

1 comentario:

Julius dijo...

Excelente aporte Mau y que bueno que retomas tu blog, felicidades, esperopronto hacer lo mismo, tengo muchos trucos por publicar, saludos