Skip to content

Instantly share code, notes, and snippets.

@leighmcculloch
Created April 20, 2025 01:11
Show Gist options
  • Save leighmcculloch/add4ce1bb73df660881fda2314e67727 to your computer and use it in GitHub Desktop.
Save leighmcculloch/add4ce1bb73df660881fda2314e67727 to your computer and use it in GitHub Desktop.
/**
* Calculates the date of Easter Sunday for a given year using the Anonymous Gregorian algorithm.
* See https://en.wikipedia.org/wiki/Computus#Anonymous_Gregorian_algorithm
*
* @param year The year for which to calculate Easter.
* @returns A Date object representing Easter Sunday for that year.
*/
function getEaster(year: number): Date {
if (year < 1583) {
throw new Error("Algorithm is valid only for Gregorian calendar years (1583 onwards).");
}
const a = year % 19;
const b = Math.floor(year / 100);
const c = year % 100;
const d = Math.floor(b / 4);
const e = b % 4;
const f = Math.floor((b + 8) / 25);
const g = Math.floor((b - f + 1) / 3);
const h = (19 * a + b - d - g + 15) % 30;
const i = Math.floor(c / 4);
const k = c % 4;
const l = (32 + 2 * e + 2 * i - h - k) % 7;
const m = Math.floor((a + 11 * h + 22 * l) / 451);
// Month: (h + l - 7 * m + 114) / 31 --> 3 = March, 4 = April
const month = Math.floor((h + l - 7 * m + 114) / 31);
// Day: ((h + l - 7 * m + 114) % 31) + 1
const day = ((h + l - 7 * m + 114) % 31) + 1;
// JavaScript Date month is 0-indexed (0=Jan, 1=Feb, ..., 3=Apr)
// The algorithm returns month 3 for March, 4 for April.
return new Date(Date.UTC(year, month - 1, day));
}
const startYear = 1900;
const endYear = 2100;
// Target date: April 20th. Month is 3 (0-indexed), Day is 20.
const targetMonth = 3;
const targetDay = 20;
const resultYears: number[] = [];
console.log(
`Searching for years between ${startYear} and ${endYear} where Easter Sunday is April 20th...`,
);
for (let year = startYear; year <= endYear; year++) {
try {
const easterDate = getEaster(year);
// Use getUTCMonth() and getUTCDate() because we created the date with UTC values.
if (
easterDate.getUTCMonth() === targetMonth &&
easterDate.getUTCDate() === targetDay
) {
resultYears.push(year);
}
} catch (error) {
// Although the range starts at 1900, the check inside getEaster handles pre-Gregorian years if the range were different.
console.error(`Could not calculate Easter for year ${year}: ${error.message}`);
}
}
if (resultYears.length > 0) {
console.log("\nFound years where Easter Sunday falls on April 20th:");
resultYears.forEach((year) => console.log(year));
} else {
console.log(
"\nNo years found in the specified range where Easter Sunday falls on April 20th.",
);
}
@leighmcculloch
Copy link
Author

1919
1924
1930
2003
2014
2025
2087
2098

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment