Skip to content

Instantly share code, notes, and snippets.

@leighmcculloch
Created April 20, 2025 01:11
Show Gist options
  • Select an option

  • Save leighmcculloch/add4ce1bb73df660881fda2314e67727 to your computer and use it in GitHub Desktop.

Select an option

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
Copy Markdown
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