Unos “conocidos” reclamaron que no solamente deseaban sacar el proximo día hábil, sino también deseaban saber cuales eran los N anteriores días habiles. Ademas se reportaron fallos con fecha sabado y/o domingo.
Por lo anterior y otras razones más, publico la v2 que ahora se llama dia_habil y se utiliza de la siguiente forma:
- Para el/los próximo(s) día(s):
1 | SELECT utilidades.dia_habil(15, current_date); |
- Para el/los anterior(es) día(s):
1 | SELECT utilidades.dia_habil(-15, current_date); |
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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | --DROP FUNCTION utilidades.dia_habil (IN in_dias int4, IN in_desde date) CASCADE; /** * Funcion que calcula el ANTERIOR o PROXIMO dia habil * * @date 2009-10-07 * @author MANUEL DIEGO PAILLAFIL GAMBOA * @email manuel@radiohead.cl * @url http://manuel.radiohead.cl/ * * @param INT * @param DATE */ CREATE OR REPLACE FUNCTION utilidades.dia_habil(in_dias integer, in_desde date) RETURNS date AS $BODY$ DECLARE fecha_actual date := in_desde; fecha_limite date; retorno date; dias_extras int4 := 0; dias_extras_alt int4 := 0; dia int4; generate_digit1 int4; generate_digit2 int4; row_fechas record; row_fechas_alt record; BEGIN IF(in_dias < 0)THEN generate_digit1 := in_dias; generate_digit2 := -1; SELECT EXTRACT(DOW FROM fecha_actual) INTO dia; IF(dia = 0)THEN fecha_actual := fecha_actual - '1 days'::interval; ELSE IF(dia = 6)THEN fecha_actual := fecha_actual - '0 days'::interval; END IF; END IF; fecha_limite := fecha_actual; ELSE generate_digit1 := 1; generate_digit2 := in_dias; SELECT EXTRACT(DOW FROM fecha_actual) INTO dia; IF(dia = 0)THEN fecha_actual := fecha_actual - '2 day'::interval; ELSE IF(dia = 6)THEN fecha_actual := fecha_actual - '1 days'::interval; END IF; END IF; fecha_limite := fecha_actual; END IF; FOR row_fechas IN SELECT fecha_actual + s.a AS fecha FROM generate_series(generate_digit1,generate_digit2,1) AS s(a) LOOP SELECT EXTRACT(DOW FROM row_fechas.fecha) INTO dia; IF(dia = 6 AND in_dias > 0)THEN dias_extras := dias_extras + 2; ELSE IF(dia = 0 AND in_dias < 0)THEN dias_extras := dias_extras - 2; END IF; END IF; END LOOP; IF(in_dias < 0)THEN generate_digit1 := in_dias + dias_extras; generate_digit2 := -1; ELSE generate_digit1 := 1; generate_digit2 := in_dias + dias_extras; END IF; FOR row_fechas_alt IN SELECT fecha_actual + s.a AS fecha FROM generate_series(generate_digit1,generate_digit2,1) AS s(a) LOOP SELECT EXTRACT(DOW FROM row_fechas_alt.fecha) INTO dia; IF(dia = 6)THEN IF(in_dias < 0)THEN dias_extras_alt := dias_extras_alt - 2; ELSE dias_extras_alt := dias_extras_alt + 2; END IF; /** * Las siguientes 7 lineas se descomentan si se desea utilizar una tabla que mantenga los feriados * con fecha absoluta(25 de Diciembre es 25/12/2009(Formato SQL, EURUPEO)) */ --ELSE IF(row_fechas_alt.fecha IN (SELECT fecha FROM utilidades.feriados WHERE fecha = row_fechas_alt.fecha AND EXTRACT(dow FROM fecha) NOT IN (0,6)))THEN -- IF(in_dias < 0)THEN -- dias_extras_alt := dias_extras_alt - 1; -- ELSE -- dias_extras_alt := dias_extras_alt + 1; -- END IF; --END IF; END IF; END LOOP; retorno := fecha_limite + ((in_dias + dias_extras_alt)::varchar || ' days')::interval; RETURN retorno; END; $BODY$ LANGUAGE 'plpgsql' VOLATILE; |
[...] Próximo día hábil en PostgreSQL base de datos, by admin. Funcion obsoleta y con errores. Favor ver versión 2 en: http://manuel.radiohead.cl/2009/dia-habil-anterior-proximo-en-postgresql/ [...]