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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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í:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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 (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

RE:Dias laborables entre 2 fechas

Publicado por Gonzalo (1 intervención) el 09/03/2020 13:55:11
Gracias, me sirvió de mucho el aporte de joseles Sanchez y Martin. Hace tiempo buscaba algo asi.
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 Vladimir (1 intervención) el 18/07/2021 09:47:16
Gracias .....
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
sin imagen de perfil
Val: 2
Ha disminuido su posición en 3 puestos en SQL Server (en relación al último mes)
Gráfica de SQL Server

Dias laborables entre 2 fechas

Publicado por Fede (1 intervención) el 26/08/2019 16:44:01
ESTA ES LA QUE VA GENTE

1
2
3
4
5
6
7
8
9
10
SET DATEFIRST 1
declare @FechaIni date = '20190901';
declare @FechaFin date = '20190930';
declare @dias int=0;
WHILE @FechaIni <= @FechaFin
BEGIN
   if  datepart(dw, @FechaIni) not in (6,7) SET @dias=@dias+1
   set @FechaIni=dateadd(dd,1,@FechaIni)
END
print @dias
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

Dias laborables entre 2 fechas

Publicado por Wladimir (1 intervención) el 29/02/2020 23:22:07
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/* ---------------------------------------------------------------------------------------------------------*/
/* Obtengo el total de dias que no sean sabados y domingos, entre dos fechas */
/* utilizando dos funciones del SQLSERVER: DATEADD, DATENAME                     */
/* ---------------------------------------------------------------------------------------------------------*/
DECLARE @ld_fdesde  date
DECLARE @ld_fsalida date
DECLARE @ld_fregreso date
DECLARE @li_contar_dias integer
 
SELECT @ld_fsalida = '2019-03-10'
SELECT @ld_fregreso= '2019-03-24'
SELECT @ld_fdesde = @ld_fsalida
SELECT @li_contar_dias = 0
 
WHILE (DATEADD(dd,1,@ld_fregreso)) <> @ld_fdesde
BEGIN
    IF DATENAME(weekday,@ld_fdesde) <> 'Saturday' AND DATENAME(weekday,@ld_fdesde)<>'Sunday'
         SELECT @li_contar_dias = @li_contar_dias + 1
    SELECT @ld_fdesde = DATEADD(d,1,@ld_fdesde)
END
 
SELECT @li_contar_dias
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