UNPKG

ethioholiday

Version:

A comprehensive Ethiopian holidays calculator that works with both Ethiopian and Gregorian calendar systems

164 lines (163 loc) 6.38 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getEthiopianHolidays = getEthiopianHolidays; exports.getHolidaysForGregorianYear = getHolidaysForGregorianYear; const ethiopian_calendar_new_1 = require("ethiopian-calendar-new"); // Fixed Ethiopian holidays (month/day in Ethiopian calendar) const FIXED_ETHIOPIAN_HOLIDAYS = [ { name: 'Enkutatash (New Year)', month: 1, day: 1, isPublicHoliday: true }, { name: 'Meskel (Finding of the True Cross)', month: 1, day: 17, isPublicHoliday: true }, { name: 'Genna (Ethiopian Christmas)', month: 4, day: 29, isPublicHoliday: true }, { name: 'Timket (Epiphany)', month: 5, day: 11, isPublicHoliday: true }, { name: 'Victory of Adwa', month: 6, day: 23, isPublicHoliday: true }, { name: "Patriots' Victory Day", month: 8, day: 27, isPublicHoliday: true }, { name: 'Downfall of the Derg', month: 9, day: 20, isPublicHoliday: true }, { name: 'National Day', month: 10, day: 20, isPublicHoliday: true }, ]; // Islamic holidays (approximate - should be calculated properly in production) const ISLAMIC_HOLIDAYS = [ { name: 'Eid al-Fitr', isPublicHoliday: true }, { name: 'Eid al-Adha', isPublicHoliday: true }, ]; /** * Calculate Ethiopian Orthodox Easter (Fasika) in Ethiopian calendar * using the Gauss algorithm adapted for Ethiopian calendar. */ function calculateFasika(ethiopianYear) { // Algorithm adapted from: // https://en.wikipedia.org/wiki/Computus#Gauss's_Easter_algorithm const a = ethiopianYear % 4; const b = ethiopianYear % 7; const c = ethiopianYear % 19; const d = (19 * c + 15) % 30; const e = (2 * a + 4 * b + 6 * d + 6) % 7; const f = d + e + 13; let month; let day; if (f <= 30) { month = 8; // Miyazya (April-May) day = f; } else { month = 9; // Ginbot (May-June) day = f - 30; } // Adjust for the Ethiopian calendar offset return { year: ethiopianYear, month, day }; } /** * Calculate Islamic holidays (approximate - replace with proper Hijri calculations) */ function calculateIslamicHolidays(gregorianYear) { // Note: These are approximations! In a real application, you should: // 1. Use a proper Hijri-Gregorian conversion library // 2. Get the dates from an authoritative Islamic calendar source // Approximate calculations (may be off by ±1 day) const eidAlFitr = { year: gregorianYear, month: 5, // May day: Math.floor(gregorianYear * 0.03 + 10) % 28 + 1 }; const eidAlAdha = { year: gregorianYear, month: 7, // July day: Math.floor(gregorianYear * 0.03 + 20) % 28 + 1 }; return [ { name: 'Eid al-Fitr', gregorianDate: eidAlFitr, ethiopianDate: (0, ethiopian_calendar_new_1.toEthiopian)(eidAlFitr.year, eidAlFitr.month, eidAlFitr.day), isPublicHoliday: true }, { name: 'Eid al-Adha', gregorianDate: eidAlAdha, ethiopianDate: (0, ethiopian_calendar_new_1.toEthiopian)(eidAlAdha.year, eidAlAdha.month, eidAlAdha.day), isPublicHoliday: true } ]; } /** * Generate all holidays for a given Ethiopian year */ function getEthiopianHolidays(ethiopianYear) { const holidays = []; // 1. Add fixed Ethiopian holidays FIXED_ETHIOPIAN_HOLIDAYS.forEach(({ name, month, day, isPublicHoliday }) => { const ethDate = { year: ethiopianYear, month, day }; holidays.push({ name, ethiopianDate: ethDate, gregorianDate: (0, ethiopian_calendar_new_1.toGregorian)(ethDate.year, ethDate.month, ethDate.day), isPublicHoliday }); }); // 2. Calculate movable Christian holidays (Fasika and related) const fasikaEth = calculateFasika(ethiopianYear); const fasikaGreg = (0, ethiopian_calendar_new_1.toGregorian)(fasikaEth.year, fasikaEth.month, fasikaEth.day); // Add Fasika (Easter) holidays.push({ name: 'Fasika (Easter)', ethiopianDate: fasikaEth, gregorianDate: fasikaGreg, isPublicHoliday: true }); // Add Siklet (Good Friday) - 2 days before Fasika const sikletEth = subtractDaysFromEthiopianDate(fasikaEth, 2); holidays.push({ name: 'Siklet (Good Friday)', ethiopianDate: sikletEth, gregorianDate: (0, ethiopian_calendar_new_1.toGregorian)(sikletEth.year, sikletEth.month, sikletEth.day), isPublicHoliday: true }); // 3. Add Islamic holidays (approximate) holidays.push(...calculateIslamicHolidays(fasikaGreg.year)); return holidays.sort((a, b) => a.gregorianDate.year !== b.gregorianDate.year ? a.gregorianDate.year - b.gregorianDate.year : a.gregorianDate.month !== b.gregorianDate.month ? a.gregorianDate.month - b.gregorianDate.month : a.gregorianDate.day - b.gregorianDate.day); } /** * Helper function to subtract days from an Ethiopian date */ function subtractDaysFromEthiopianDate(ethDate, days) { let jdn = ethToJDN(ethDate.year, ethDate.month, ethDate.day); jdn -= days; return jdnToEth(jdn); } // JDN conversion functions (same as in your calendar implementation) const JD_EPOCH_OFFSET_AMETE_MIHRET = 1724220; function ethToJDN(year, month, day) { return JD_EPOCH_OFFSET_AMETE_MIHRET + 365 * (year - 1) + Math.floor(year / 4) + 30 * (month - 1) + (day - 1); } function jdnToEth(jdn) { const r = jdn - JD_EPOCH_OFFSET_AMETE_MIHRET; const year = Math.floor((r + 366) / 365.25); const newYearJDN = ethToJDN(year, 1, 1); const daysPassed = jdn - newYearJDN; let month; let day; if (daysPassed < 30 * 12) { month = Math.floor(daysPassed / 30) + 1; day = (daysPassed % 30) + 1; } else { month = 13; day = daysPassed - 30 * 12 + 1; } return { year, month, day }; } // Utility function to get holidays for a Gregorian year function getHolidaysForGregorianYear(gregorianYear) { // Convert Gregorian year to approximate Ethiopian year const ethiopianYear = gregorianYear - 8; const holidays = getEthiopianHolidays(ethiopianYear); // Filter holidays that fall in the Gregorian year return holidays.filter(h => h.gregorianDate.year === gregorianYear); }