Función en SQL para el cálculo de días laborables

  • 20 de abril de 2005
  • Valoración:
  • 16 Comentarios
  • Lenguaje SQL
Función que nos permite calcular el número de días laborables entre una fecha y otra, con las validaciones pertinentes.
/*Primeramente declaramos que vamos a crear una funcion, en este caso se llama Dif Dias y recibe dos parámetros, la fecha inicial del período y la final*/

CREATE FUNCTION DifDias(@StartDate DATETIME,@EndDate DATETIME)
RETURNS integer
AS
Begin

//Con esta variable calculamos cuantos dias "normales" hay en el rango de fechas

DECLARE @DaysBetween INT

//Con esta variable acumulamos los dias totales

DECLARE @BusinessDays INT

//esta variable nos sirve de contador para saber cuando lleguemos al ultimo dia del rango

DECLARE @Cnt INT

/*esta variable es la que comparamos para saber si el dia que esta calculando es sábado o domingo*/

DECLARE @EvalDate DATETIME

/*Esta par de variables sirven para comparar las dos fechas, si son iguales, la funcion nos regresa un 0*/

DECLARE @ini VARCHAR(10)
DECLARE @fin VARCHAR(10)

//Inicializamos algunas variables

SELECT @DaysBetween = 0
SELECT @BusinessDays = 0
SELECT @Cnt=0

//Calculamos cuantos dias normales hay en el rango de fechas SELECT @DaysBetween = DATEDIFF(DAY,@StartDate,@EndDate) + 1

/*Ordenamos el formato de las fechas para que no importando como se proporcionen se comparen igual*/

SELECT @ini = (SELECT CAST((CAST(datepart(dd,@StartDate)AS
VARCHAR(2))+'/'+ CAST(datepart(mm,@StartDate)AS
VARCHAR(2))+'/'+CAST(datepart(yy,@StartDate)AS VARCHAR(4))) as
varchar(10)))
SELECT @fin = (SELECT CAST((CAST(datepart(dd,@EndDate)AS
VARCHAR(2))+'/'+ CAST(datepart(mm,@EndDate)AS VARCHAR(2))+'/'+
CAST(datepart(yy,@EndDate)AS VARCHAR(4)))as varchar(10)))

//Se comparan las dos fechas

IF @ini <>@fin
BEGIN

/*Si la diferencia de fechas es igual a dos, es porque solo ha transcurrido un dia, asi que solo se valida que no vaya a marcar dias de mas*/

IF @DaysBetween = 2
BEGIN
SELECT @BusinessDays = 1
END
ELSE
BEGIN
WHILE @Cnt < @DaysBetween
BEGIN

/*Se Iguala la fecha a que vamos a calcular para saber si es sabado o domingo en la variable @EvalDate sumandole los dias que marque el contador, el cual no debe ser mayor que el numero total de dias que hay en el rango de fechas*/

SELECT @EvalDate = @StartDate + @Cnt

/*Utilizando la funcion datepart con el parametro dw que calcula que dia de la semana corresponde una fecha determinada, determinados que no sea sabado (7) o domingo (1)*/

IF ((datepart(dw,@EvalDate) <> 1) and
(datepart(dw,@EvalDate) <> 7) )
BEGIN

/*Si no es sabado o domingo, entonces se suma uno al total de dias que queremos desplegar*/

SELECT @BusinessDays = @BusinessDays + 1
END

//Se suma un dia mas al contador

SELECT @Cnt = @Cnt + 1
END
END
END
ELSE
BEGIN

//Si fuese cierto que las fechas eran iguales se despliegue cero

SELECT @BusinessDays = 0
END

//Al finalizar el ciclo, la funcion regresa el numero total de dias

return (@BusinessDays)
END

Comentarios

Tomas Ochoa

05/5/2005
Excelente Funcion !!!!!!!, Me sirvio mucho gracias

luis

04/1/2007
supongo que es muy interesante, pero vengo leyendome el tutorial desde el principio y da un salto enorme desde el anterior articulo a este, no me he enterado ni del 10% de lo que se explica, sin embargo los anteriores estupendos. esperemos que los siguientes sean mejores...

toribio

20/2/2009
ok gracia

pedropablo

19/4/2009
manual sql
muy bien explicado el tema ,si se pueden añadir ejemplos de consultas realizadas con sql ,utilizando recordset en access seria de gran utilidad a personas que recien comienzan con este tema

fernando

28/5/2009
funcion fecha
idem comentario anterior, muy bueno los anteriores pero a este le faltó mas explicacion, "pegó un salto"

Cristian

18/8/2009
Dias
Esta buenisima la funcion, me sirvio mucho, mil gracias

FelipeSQL-1977

04/3/2010
Bulbasur
Alguien sabe dónde puedo encontrar a Bulbasur en Pokémon Perla? En serio, lo necesito. Aps, y ya de paso, recién empecé a trabajar en una empresa que hace SQL, pa mí esto es como los donuts, me los como pero ni idea de hacerlos. En fin, alguien podría leerme el manual de todo esto por teléfono? Obviamente llamaría yo. También agradecería que alguien me diera un teléfono o correo para que fuera haciendo las cosas que me manden en el trabajo. Gracias !!!
P.D.: si sabeis lo de Bulbasur genial eh :)

TORTOS

05/3/2010
Procedimiento Almacenado
Execelente aporte, lo implemente en una aplicación que estoy desarrollando y funciona perfectamente, no obstante me gustaria saber como puedo incluir los dias feriados (festivos) que seria a los diaslaborados-los sábados y domingos - dia festivos (en mi caso los tengo almacenados en un tabla)

Saludos cordiales, Tortos Costa Rica

Dirko

20/5/2010
dias no laborables
Es bueno aclarar que esta funcion no sirve cuando entre las dos fechas hay dias no habiles (que no se trabaja o no laborables) como fechas patrias (por ejemplo dia de la independencia o fecha del nacimiento del algun procer de independencia) o fechas religiosas como semana santa o alguna otra fecha no laborable como el 24 de diciembre o 1ro de Mayo. Para actualizar la funcion que reste de los dias laborables habria que guardar en una tabla los dias no laborales, hacer select de dicha tabla haciendo count de los dias no laborables entre las fecha inicial y la fecha final y restando del calculo de la funcion, el resultado del select

Para el resto de los casos es perfecta y sirve como ejemplo perfecto.

Gracias por la funcion.

Salu2.

enrique

29/1/2011
Funcion de dias sabado y domingo
he creado la funcion y los valores que me retornan son CERO (0), aun cambiando las fechas hasta por diferencias de anos.

por favor pueden enviarme algun ejemplo de la funcion ejecutandose normalmente.

zlus0

26/2/2011
Otra forma
Yo hice esta:

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!

Felix

20/9/2011
Felicitarlos por el articulo
Muy bien, ya lo probe la funcion y jalo perfectamente, bueno tuve que hacer unas modificaciones en los parametros de entrada de la funcion pero muy bien..

Saludos

Amiga

30/10/2011
Consulta
NO se por que pero a mi no me funciona la funcion DatePart en SQL Server 2005, esta en español. Le he cambiado de todas la formas la fecha pero NO. Inserte el siguiente comano SELECT DATEPART(MI, ´2007-10-30 12:15:32.1234567 +05:10´). Y nada si aguien sabe por favor ayudarme.
Gracias

cradsma31

13/3/2012
dateadd en sql
hola a todos, me gustaria pudieran ayudarme con el codigo de lo siguiente (ya sea en VB, sql, accessl ) tengo una lista de tramites con dias a contar de plazo ejemplo si es (clave a, 20 dias ), (clave b,40 dias) etc y otra tabla de registros donde ubico la clave, fecha, necesito saber la fecha de plazo en otra tabla de todos mis registros de acuerdo a estas condiciones, todos los dias son habiles, (seria un rollo si pusiera que algunos son naturales y otros son habiles) , gracias saludos

Diebolas

12/6/2012
Correción
Para que calcule perfectamente hay que agregarle a lo último lo siguiente, por que si no cuando los días transcurridos son más de 1 calcula un día demás:

if @Cnt > 0
return (@DiasLaborales) -1

return (@DiasLaborales)
END

morita666_@hotmail.com

29/5/2013
bbuena ayuda pero como devuelvo la fecha en la que se quedo el conteo
HOLA DE ANTEMANO AGRADESCO SU APORTACION...PUES DE GRAN AYUDA LO QUE QUIEROS SABER ES COMO ME PUEDE DEVOLVER LA FECHA EN LA QUE QUEDO EL CONTEO ES DECIR QUIERO CALCULAR UN PLAZO DE 20 O 30 DIAS A UNA FECHA Y QUE ME DIGA EN QUE FECHA VENCE SINCONTAR SABADOS Y DOMINGOS...GRACIAS

Compartir