Skip to content

Instantly share code, notes, and snippets.

@vjnrv
Last active June 27, 2017 18:46
Show Gist options
  • Save vjnrv/2302190 to your computer and use it in GitHub Desktop.
Save vjnrv/2302190 to your computer and use it in GitHub Desktop.
Procedure para calcular data da Páscoa (PostgreSQL)
-- Retorna a data da Pascoa
-- @author Pedro Junior
-- @param ANO integer
-- @return Date
CREATE OR REPLACE FUNCTION getDataPascoa (ANO numeric(4) DEFAULT date_part('year', NOW()))
RETURNS DATE AS $$
DECLARE
DIA numeric(2); -- Dia do Natal
MES numeric(2); -- Mês do Natal
X numeric(2); -- Valor de X de acordo com a faixa de anos
Y numeric(2); -- Valor de Y de acordo com a faixa de anos
aM numeric(2); -- Valor para MOD de A
bM numeric(2); -- Valor para MOD de B
cM numeric(2); -- Valor para MOD de C
dM numeric(2); -- Valor para MOD de D
A numeric(2); -- Ano MOD aM
B numeric(2); -- Ano MOD bM
C numeric(2); -- Ano MOD cM
D numeric(2); -- (aM * A + X) MOD dM
E numeric(2); -- (2 * B + bM * C + 6 * D + Y) MOD cM
DeE numeric(2); -- (D + E)
DATA date; -- Data da Pascoa Calculada
BEGIN
X =
CASE
WHEN ANO BETWEEN 1582 AND 1699 THEN 22
WHEN ANO BETWEEN 1700 AND 1799 THEN 23
WHEN ANO BETWEEN 1800 AND 2199 THEN 24
WHEN ANO BETWEEN 2200 AND 2299 THEN 25
END;
Y =
CASE
WHEN ANO BETWEEN 1582 AND 1699 THEN 2
WHEN ANO BETWEEN 1700 AND 1799 THEN 3
WHEN ANO BETWEEN 1800 AND 1899 THEN 4
WHEN ANO BETWEEN 1900 AND 2099 THEN 5
WHEN ANO BETWEEN 2100 AND 2199 THEN 6
WHEN ANO BETWEEN 2200 AND 2299 THEN 7
END;
aM = 19;
bM = 4;
cM = 7;
dM = 30;
A = mod(ANO, aM);
B = mod(ANO, bM);
C = mod(ANO, cM);
D = mod((aM * A + X), dM);
E = mod((2 * B + bM * C + 6 * D + Y), cM);
DeE = D + E;
IF (DeE > 9) THEN
DIA = DeE - 9;
MES = 4;
-- Casos que só ocorrem duas vezes por século:
-- Se o Dia for 26 então corrige para uma semana antes
IF (DIA = 26) THEN
DIA = DIA - cM;
END IF;
-- Se o Dia for 25 e D for 28 e A > 10 então corrige o dia pra 18
IF (DIA = 25 AND D = 28 AND A > 10) THEN
DIA = 18;
END IF;
ELSE
DIA = DeE + 22;
MES = 3;
END IF;
DATA = to_date(ANO || '-' || MES || '-' || DIA, 'YYYY-MM-DD');
RETURN DATA;
END
$$ LANGUAGE 'PLPGSQL';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment