SQL Server - Dias laborables entre 2 fechas

   
Vista:

Dias laborables entre 2 fechas

Publicado por Pablo (5 intervenciones) el 18/11/2010 21:39:57
Estimados Amigos

Tengo ahora el siguiente problema, tengo que hallar los dias laborables (que no cuente sabados ni domingos) entre un rango de fechas (fecha_inicio y fecha_fin), he probado con esta funcion que encontre en internet pero siempre me devuelve NULL

CREATE FUNCTION dbo.DiasLaborales
( @StartDate datetime,
@EndDate datetime )
RETURNS INT
AS

BEGIN
DECLARE @WorkDays int, @FirstPart int
DECLARE @FirstNum int, @TotalDays int
DECLARE @LastNum int, @LastPart int
IF (DATEDIFF(day, @StartDate, @EndDate) < 2)

BEGIN
RETURN ( 0 )
END
SELECT
@TotalDays = DATEDIFF(day, @StartDate, @EndDate) - 1,
@FirstPart = CASE DATENAME(weekday, @StartDate)
WHEN 'Sunday' THEN 6
WHEN 'Monday' THEN 5
WHEN 'Tuesday' THEN 4
WHEN 'Wednesday' THEN 3
WHEN 'Thursday' THEN 2
WHEN 'Friday' THEN 1
WHEN 'Saturday' THEN 0
END,
@FirstNum = CASE DATENAME(weekday, @StartDate)
WHEN 'Sunday' THEN 5
WHEN 'Monday' THEN 4
WHEN 'Tuesday' THEN 3
WHEN 'Wednesday' THEN 2
WHEN 'Thursday' THEN 1
WHEN 'Friday' THEN 0
WHEN 'Saturday' THEN 0
END
IF (@TotalDays < @FirstPart)

BEGIN
SELECT @WorkDays = @TotalDays
END
ELSE

BEGIN
SELECT @WorkDays = (@TotalDays - @FirstPart) / 7
SELECT @LastPart = (@TotalDays - @FirstPart) % 7
SELECT @LastNum = CASE
WHEN (@LastPart < 7) AND (@LastPart > 0) THEN @LastPart - 1
ELSE 0
END
SELECT @WorkDays = @WorkDays * 5 + @FirstNum + @LastNum
END
RETURN ( @WorkDays +1)
END

la ejecuto de la siguiente manera
select dbo.DiasLaborales(fechaini, fechafin) from vacaciones

Que puede estar mal en esta funcion, o si hay alguna manera mas sencilla de poder encontrar los dias laborales.

Saludos
Pablo
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

RE:Dias laborables entre 2 fechas

Publicado por Loría (56 intervenciones) el 19/11/2010 00:15:53
Buenas tardes.

Pregunta: ¿Tienes que hallar la cantidad de días entre estas fechas o que te muestre en el resultado las fechas que cumplen esta regla?

Saludos.

Loría
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Dias laborables entre 2 fechas

Publicado por Loría (56 intervenciones) el 19/11/2010 00:53:39
Buenas tardes.

Ya he creado esta función que me parece hace lo que necesitas. Por favor pruébala y nos cuentas como te va.

CREATE FUNCTION dbo.DiasLaborales
( @FechaInicial datetime,
@FechaFinal datetime )
RETURNS INT
AS
BEGIN

DECLARE @varfecha DATETIME
DECLARE @diaslaborales int

SET @varfecha = @FechaInicial
SET @diaslaborales = 0

WHILE (@varfecha<>(@FechaFinal + 1))
BEGIN
IF (DATEPART(dw,@varfecha) NOT IN (7,1))
BEGIN
SET @diaslaborales = @diaslaborales +1
END
SET @varfecha = @varfecha + 1
END
RETURN @diaslaborales
END

La función no hace validaciones así que debes agregárselas si las necesitas. Si lo que necesitas es mostrar en el resultado las fechas que son laborales, simplemente pon este mismo código para un procedimiento (ya que las funciones comunes no pueden devolver información de SELECT's) y le quitas la línea:

SET @diaslaborales = @diaslaborales +1

y pones en su lugar el código que muestre la variable @varfecha

Espero te haya ayudado.

Saludos.

Loría.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Dias laborables entre 2 fechas

Publicado por Pablo (5 intervenciones) el 19/11/2010 18:40:28
Hola Loría

He probado la funcion que me proporcionaste y ha funcionado bien salvo que tuve que realizar una ligera modificacion para que me sumara correctamente los dias. Reemplaze el while que me escribiste por ese otro

CREATE FUNCTION dbo.DiasLaborales
( @FechaInicial datetime,
@FechaFinal datetime )
RETURNS INT
AS
BEGIN

DECLARE @varfecha DATETIME
DECLARE @diaslaborales int

SET @varfecha = @FechaInicial
SET @diaslaborales = 0

/*WHILE (@varfecha<>(@FechaFinal + 1)) */
WHILE ((@fechafinal + 1) > @varfecha)
BEGIN
IF (DATEPART(dw,@varfecha) NOT IN (6,7))
BEGIN
SET @diaslaborales = @diaslaborales +1
END
SET @varfecha = @varfecha + 1
END
RETURN @diaslaborales
END

Muchas gracias por todo, voy a seguir probandolo y les comento.

Saludos
Pablo
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Dias laborables entre 2 fechas

Publicado por Loría (56 intervenciones) el 20/11/2010 00:14:32
Buenas tardes.

Perfecto Pablo esperaremos tus comentarios.

Saludos.

Loría.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Dias laborables entre 2 fechas

Publicado por jayjay (1 intervención) el 17/11/2011 17:34:11
Funciona muy bien la solución de Pablo.
Lo único es que si se compara con GetDate sale la diferencia mal (un día más).

Para solucionar eso, hay que formatear la fecha de hoy : GETDATE()
select dbo.DiasLaborales(FechaIni,CONVERT(Datetime,FLOOR(CONVERT(Float,GetDate()))))
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Dias laborables entre 2 fechas

Publicado por Joseles Sánchez (1 intervención) el 10/08/2012 20:23:54
Como dice jayjay la función funciona bien, nada más una observación para cuando hagan cálculo entre fechas... Deben de utilizar el tipo de dato DATE y no DATETIME. Lo anterior para que no se tome en cuenta la hora en los cálculos y así no se tengan que hacer conversiones.

Por lo cual la función quedaría así:

ALTER FUNCTION dbo.GetDiasLaborales
( @FechaInicial DATE,
@FechaFinal DATE )
RETURNS INT
AS
BEGIN

DECLARE @varfecha DATE
DECLARE @diaslaborales int

SET @varfecha = @FechaInicial
SET @diaslaborales = 0


/*WHILE (@varfecha<>(@FechaFinal + 1)) */
WHILE ( DATEADD(dd,1,@fechafinal) > @varfecha)
BEGIN
IF (DATEPART(dw,@varfecha) NOT IN (1,7))
BEGIN
SET @diaslaborales = @diaslaborales + 1
END

SET @varfecha =DATEADD(dd,1,@varfecha)
END

RETURN @diaslaborales

END


Se invocaria asi:

Ejempo:: select dbo.GetDiasLaborales('2012-08-01',GETDATE()+3)
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Dias laborables entre 2 fechas

Publicado por Martin mcollazosb@gmail.com (1 intervención) el 05/07/2013 00:44:47
Excelente aporte, tambien se puede agregar a la función para que no incluya días festivos.

IF (DATEPART(dw,@varfecha) NOT IN (1,7)) and @varfecha not in (select fecha from DiasFestivos)

En este caso DiasFestivos es una tabla con los feriados y a la cual se le puede dar mantenimiento.

Saludos
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Dias laborables entre 2 fechas

Publicado por AJAvila (1 intervención) el 12/04/2014 18:34:06
Gracias! Muy buen aporte, excelente...! Me fue de gran ayuda.
Solo una observación, en el ejemplo que muestra Joseles Sánchez, no entendí por qué colocó +3.

"Ejempo:: select dbo.GetDiasLaborales('2012-08-01',GETDATE()+3)"

Para adapatarlo a lo que necesitaba eliminé el +3. Y hace el calculo de los días de manera correcta!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar