Función en MySQL para contar días entre dos fechas sin contar sábados ni domingos

Después de darle muchas vueltas he encontrado esta útil función en los foros de MySQL que permite calcular el número de días que han transcurrido entre dos fechas sin contar fines de semana.

Espero que os sea tan útil como a mí.

DELIMITER $$
 
DROP FUNCTION IF EXISTS `workdaydiff`$$
CREATE FUNCTION workdaydiff(b date, a date) RETURNS int(11)
    DETERMINISTIC
    COMMENT 'working day difference for 2 dates'
BEGIN
 
DECLARE freedays int;
 
SET freedays = 0;
SET @x = DATEDIFF(b, a);
IF @x<0 THEN
SET @m = a;
SET a = b;
SET b = @m;
SET @m = -1;
ELSE
SET @m = 1;
END IF;
SET @x = abs(@x) + 1;
 
SET @w1 = WEEKDAY(a)+1;
SET @wx1 = 8-@w1;
IF @w1>5 THEN
SET @w1 = 0;
ELSE
SET @w1 = 6-@w1;
END IF;
 
SET @wx2 = WEEKDAY(b)+1;
SET @w2 = @wx2;
IF @w2>5 THEN
SET @w2 = 5;
END IF;
 
SET @weeks = (@x-@wx1-@wx2)/7;
SET @noweekends = (@weeks*5)+@w1+@w2;
 
SET @result = @noweekends-freedays;
RETURN @result*@m;
END$$
 
DELIMITER ;

24 thoughts on “Función en MySQL para contar días entre dos fechas sin contar sábados ni domingos

  1. Disculpa mi ignorancia, una vez creada la funcion, como haria para que ejecutar dicha funcion? Les comento para que quiero saber y corriganme en caso de que no se pueda hacer con mysql. Estoy desarrollando un sistema de facturacion y quiero generar mis facturas (solo en tabla) de todos los clientes el 1er dia de cada mes. Gracias de ante mano

  2. Una vez creada la función puedes acceder a ella como si fuera una función “normal” de MySQL. Por ejemplo:

    select * from facturas where workdaydiff(fecha_factura, now())>’5′;

  3. si pero estas haciendo consulta a una tabla y llamas a una funcion lo que yo de verdad quiero es llamar la funcion, sin hacer select en ninguna tabla

  4. Aca le paso otra funcion mas pequeña q calcula lo mismo:

    CREATE DEFINER=`root`@`localhost` FUNCTION `sp_ContarDias`(a DATE,b DATE) RETURNS int(11)
    BEGIN
    DECLARE a1,d,di,df,ban,ban1,resultado INT;
    SET d=DATEDIFF(b,a)+1;
    SET di=DAYOFWEEK(a);
    SET ban=1;
    SET ban1=0;
    WHILE ban<d DO
    IF (di=8) THEN
    SET di=1;
    END IF;
    IF (di=6 OR di=7) THEN
    SET ban1=(ban1+1);
    END IF;
    SET di=(di+1);
    SET ban=(ban+1);
    END WHILE;
    SET resultado=(d-ban1);
    RETURN abs(resultado);
    END

    Para invocar la funcion solo es:
    SELECT sp_ContarDias(Fecha_Inicial,Fecha_Final);
    Ojala le sirva nos vemos bye.

  5. Hola..

    disculpa la ignorancia. donde creo esa funcion?. como hago para trabajar con php y llamar la funcion.. Mi problema es el siguiente.

    TEngo una fecha de Prestamo de libros Pero dependiendo del tipo le sumo n dias sin contar sabados y domingos que seria la fecha de entrega.
    Ahora necesito calcular la diferecnia de dias que hay entre la fecha de entrega y la fecha en que se devuelve realmente el libro. dado el caso que se pase de la fecha de entregarlo.. entonces para eso se cobra una multa por los dias pasados.

  6. necesito un programa donde permita reservar deacuerdo al as fechas donde permita registrar fechas que aun no han sido dados de alta y que calcule el numero de dias entre ls dos fechas

  7. Hola muy buenos dias muy buen aporte pana, un detallito si se puede y lo aceptas, el resultado que devuelve la funcion tiene un dia de más. Saludos!

  8. depende desde donde la quieres llamar si la quieres invocar desde linea de comandos si es con un SELECT

  9. Muchas gracias Bro!!!
    Tu función me funcionó perfectamente!!!

    Cabe decir, que solo la personalicé un poquito…
    pero perfecto!!!

    De nuevo, muchas gracias Bro!!!

  10. RETO:
    Quien Me AYUDA a adicionarle a la función workdaydiff los días feriados (festivos) ?? que estén registrados en una tabla.
    Gracias.

  11. RETO COMPLETADO:
    Gracias a la comunidad de internet por hacerme cada día mejor.
    esta es la solucion para restar los dias feriados (día de fiesta) sábado y domingos, solo día hábiles.
    estas es la funcion de mysql:
    Favor dejar tu comentario si te sirvio. like.

    DELIMITER $$
    CREATE FUNCTION workdaydiff(b DATE, a DATE) RETURNS INT(11)
    DETERMINISTIC
    COMMENT ‘working day difference for 2 dates’
    BEGIN

    DECLARE freedays INT;

    SET freedays = 0;
    SET @X = DATEDIFF(b, a);
    IF @X5 THEN
    SET @w1 = 0;
    ELSE
    SET @w1 = 6-@w1;
    END IF;

    SET @wx2 = WEEKDAY(b)+1;
    SET @w2 = @wx2;
    IF @w2>5 THEN
    SET @w2 = 5;
    END IF;

    SET @weeks = (@X-@wx1-@wx2)/7;
    SET @noweekends = (@weeks*5)+@w1+@w2;

    SET @result = @noweekends-freedays;

    SET @feriado=(SELECT COUNT(*) FROM dias_feriados WHERE fer_dia BETWEEN a AND b);

    RETURN (@result*@m)-@feriado;

    END$$

    DELIMITER ;

  12. HOLA ME PARECE UN MAGINIFICO APORTE PUES ME FUNCIONA PERO NO LE ENTIENDO MUY BIEN AL PROCESO NO SE SIA LGUIEN ME PUEDE COMENTAR LASLINEAS..GRACIAS

  13. HOLA ALGUIEN ME PUEDE AYUDAR…LO QUE PRETENDO HACER ES INSERTAR UNA FECHA N A LA CUAL LE ASIGNO UN INTERVALO DE N DIAS PARA EXPIRAR ESE RESULTADO DEBE CONTAR LOS DIAS SINSABADOS Y DOMINGOS Y ARROJARME EN QUE FECHA ESTAR VENCIENDO….

  14. RETO:
    Quien Me AYUDA a adicionarle a la función workdaydiff : (fecha_inicio, cantdiashabiles)
    como resultado debe darme la fecha final.
    Gracias.

  15. Esta fue nuestra solución al final, creo que es mas clara, ademas de que pueden agregar una entidad en donde almacenen los dias feriados y agregarlos facilmente a estes Stored Procedure.

    CREATE DEFINER=`root`@`localhost` FUNCTION `contarDiasHabiles`(fechaInicial DATE, fechaFinal DATE) RETURNS int(11)
    BEGIN
    DECLARE contadorDiasHabiles INT;
    DECLARE fechaAuxiliar DATE;

    SET contadorDiasHabiles = 0;

    if(DATEDIFF(fechaFinal, fechaInicial))=1
    end REPEAT;
    return contadorDiasHabiles;
    END

  16. Lo copio nuevamente, porque no se guardo bien en la entrada anterior.

    CREATE DEFINER=`root`@`localhost` FUNCTION `contarDiasHabiles`(fechaInicial DATE, fechaFinal DATE) RETURNS int(11)
    BEGIN
    DECLARE contadorDiasHabiles INT;
    DECLARE fechaAuxiliar DATE;
    SET contadorDiasHabiles = 0;
    if(DATEDIFF(fechaFinal, fechaInicial))=1
    end REPEAT;
    return contadorDiasHabiles;
    END

Deja un comentario