# How to calculate the Easter date in PL/SQL

Patrick Sinke

Ever wondered how they Easter date is determined? And, even more important, how it is to be maintained in you application. Manually updating the date every year is an option, but it’s always better to calculate it on the fly. It’s not easy because it depends on the age of the moon at january 1st and uses the moonyear cycle.

So, here’s some pl/sql which calculates Easter sunday for any given year:

create or replace function bepaal_paasdatum( p_jaar in number default to_numbeR(to_char( sysdate, ‘yyyy’) )) return date is
VolleMaan    Date;
GuldenGetal  pls_Integer;
SchrikkelDg  pls_Integer := 14;
Epacta       pls_Integer;
KritEpacta   pls_Integer;
begin
/* first we calculate the “golden number” of the year; we divide the year with the years in a moonyear cycle (19), and add 1
(see http://en.wikipedia.org/wiki/Golden_numbers)
*/
Guldengetal := mod( p_jaar, 19 ) +1;
/*
epacta is the age of the moon at januari 1st
*/
Epacta      := mod((GuldenGetal * 11 )- SchrikkelDg + 2, 30);
/*
calculate the full moons in a year
*/
VolleMaan   := to_Date(’13-03-‘||to_char( p_jaar), ‘dd-mm-yyyy’ ) + 31 – Epacta;
If (mod( p_jaar , 4) = 0 and mod(p_jaar, 100) != 0 ) or mod(p_jaar, 400) = 0
Then
VolleMaan := VolleMaan – 1;
end if;

If VolleMaan < to_Date(’22-03-‘||to_char( p_jaar), ‘dd-mm-yyyy’ )
Then
If GuldenGetal > 11
Then
KritEpacta := 26;
Else
KritEpacta := 25;
End If;

If Epacta < KritEpacta
Then
VolleMaan := VolleMaan + 29;
Else
VolleMaan := VolleMaan + 30;
End If;
End If;
vollemaan := vollemaan +1 ;
while to_char(vollemaan, ‘d’) != 1 –zondag zoeken
loop
vollemaan := vollemaan + 1;
end loop;

return( VolleMaan   );
end;
/

The results:

PATRICK> begin
2   for i in 1990 .. 2010
3  loop
4  dbms_output.put_line( ‘jaar ‘||i||’; ‘|| bepaal_paasdatum(i));
5  end loop;
6  end;
7  /
jaar 1990; 15-APR-90
jaar 1991; 31-MAR-91
jaar 1992; 19-APR-92
jaar 1993; 11-APR-93
jaar 1994; 03-APR-94
jaar 1995; 16-APR-95
jaar 1996; 07-APR-96
jaar 1997; 30-MAR-97
jaar 1998; 12-APR-98
jaar 1999; 04-APR-99
jaar 2000; 23-APR-00
jaar 2001; 15-APR-01
jaar 2002; 31-MAR-02
jaar 2003; 20-APR-03
jaar 2004; 11-APR-04
jaar 2005; 27-MAR-05
jaar 2006; 16-APR-06
jaar 2007; 08-APR-07
jaar 2008; 20-APR-08
jaar 2009; 12-APR-09
jaar 2010; 04-APR-10

PL/SQL procedure successfully completed.

PATRICK>

I’ve checked the dates against easter dates found on internet, and it seems right. Except…. the date for next year! Sources on internet mention March 23th, 2008, but my function returns April 20th.

I hate to say I have no clue where the problem is. So, if you plan to use my function you’ll either should find the bug or implement it after 2008! Some people suggested I have a real Easter Egg in my code….

## 6 thoughts on “How to calculate the Easter date in PL/SQL”

1. fortius says:

Can you tell me what is “zondag zoeken” in your code ??

2. Anton Scheffer says:

I don’t like wordpress. it changes my quotes “‘”, it changes my formating and it cuts my text when I use a < sign.

In the above comment you should add the following line
< 10

3. Anton Scheffer says:

You use the internet to check your values, but you can also use it for querying your values:

[pre]

select 2000 + level
, cast( to_timestamp_tz( extractValue( HTTPURITYPE( ‘www.holidaywebservice.com/Holidays/GBSCT/Dates/GBSCTHolidayDates.asmx/GetEaster?year=’
|| to_char( 2000 + level )
).getXML()
, ‘/dateTime’
, ‘xmlns=”http://www.27seconds.com/Holidays/GBSCT/Dates/”‘
)
, ‘YYYY-MM-DD”T”HH24:MI:SS.FF7TZH:TZM’
) as date
)
from dual connect by level

4. This blog again proves that everything has been done before 🙂 thanks for your input!

## Wednesday 27th June - free mini-conference at our place (AMIS Academy)

Facebook0TwitterLinkedinThis Wednesday, 27th June, we host another AMIS Academy – a mini-conference with 16 one-hour presentations, four parallel tracks, most of them open to anyone who wants to come and visit us. The sessions are in Dutch, the location is our office in Nieuwegein, the presenters are mostly AMIS consultants […]