Created
April 20, 2025 01:11
-
-
Save leighmcculloch/add4ce1bb73df660881fda2314e67727 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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.", | |
); | |
} |
Author
leighmcculloch
commented
Apr 20, 2025
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment