drop function if exists easter_date;
delimiter go
create function easter_date(yr year) returns date deterministic
begin
declare a, b, c, d, e, k, m, n, p, q int;
declare easter date;
set k = floor( yr / 100 );
set a = mod( yr, 19 );
set b = mod( yr, 4 );
set c = mod( yr, 7 );
set q = floor( k / 4 );
set p = floor(( 13 + 8 * k) / 25 );
set m = mod( (15-p+k-q), 30 );
set d = mod( (19 * a + m), 30 );
set n = mod( (4+k-q), 7 );
set e = mod( (2*b+4*c+6*d+n), 7 );
return case
when d + e <= 9 then concat_ws('-', yr, '03', 22 + d + e)
when d = 29 and e = 6 then concat_ws('-', yr, '04-19')
when d = 28 and e = 6 and a > 10 then concat_ws('-', yr, '04-18')
else concat_ws('-', yr, '04', lpad(d + e - 9, 2, 0))
end;
end;
go
delimiter ;
select easter_date(2018);
+-------------------+
| easter_date(2018) |
+-------------------+
| 2024-04-01 |
+-------------------+