Skip to content

Commit 40a065a

Browse files
committed
Export getHolidaysOnDate as a function outside of HebrewCalendar wrapper class #475
1 parent 4ea4b83 commit 40a065a

File tree

7 files changed

+103
-81
lines changed

7 files changed

+103
-81
lines changed

src/hebcal.ts

Lines changed: 10 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,12 @@ import {TimedEvent, HavdalahEvent} from './TimedEvent';
4242
import {Event, flags} from './event';
4343
import {Sedra, getSedra_} from './sedra';
4444
import {hallel_} from './hallel';
45-
import {getHolidaysForYear_, HolidayYearMap} from './holidays';
45+
import {
46+
getHolidaysForYear_,
47+
getHolidaysForYearArray,
48+
getHolidaysOnDate,
49+
HolidayYearMap,
50+
} from './holidays';
4651
import {MevarchimChodeshEvent} from './MevarchimChodeshEvent';
4752
import {HolidayEvent} from './HolidayEvent';
4853
import {Location} from './location';
@@ -351,20 +356,6 @@ function setOptionsFromMask(options: CalOptions): number {
351356
return m;
352357
}
353358

354-
/**
355-
* @private
356-
*/
357-
function observedInIsrael(ev: Event): boolean {
358-
return ev.observedInIsrael();
359-
}
360-
361-
/**
362-
* @private
363-
*/
364-
function observedInDiaspora(ev: Event): boolean {
365-
return ev.observedInDiaspora();
366-
}
367-
368359
/**
369360
* HebrewCalendar is the main interface to the `@hebcal/core` library.
370361
* This namespace is used to calculate holidays, rosh chodesh, candle lighting & havdalah times,
@@ -703,20 +694,7 @@ export class HebrewCalendar {
703694
* @param il use the Israeli schedule for holidays
704695
*/
705696
static getHolidaysForYearArray(year: number, il: boolean): HolidayEvent[] {
706-
const yearMap = getHolidaysForYear_(year);
707-
const startAbs = HDate.hebrew2abs(year, TISHREI, 1);
708-
const endAbs = HDate.hebrew2abs(year + 1, TISHREI, 1) - 1;
709-
let events: HolidayEvent[] = [];
710-
const myFilter = il ? observedInIsrael : observedInDiaspora;
711-
for (let absDt = startAbs; absDt <= endAbs; absDt++) {
712-
const hd = new HDate(absDt);
713-
const holidays = yearMap.get(hd.toString());
714-
if (holidays) {
715-
const filtered: HolidayEvent[] = holidays.filter(myFilter);
716-
events = events.concat(filtered);
717-
}
718-
}
719-
return events;
697+
return getHolidaysForYearArray(year, il);
720698
}
721699

722700
/**
@@ -728,17 +706,7 @@ export class HebrewCalendar {
728706
date: HDate | Date | number,
729707
il?: boolean
730708
): HolidayEvent[] | undefined {
731-
const hd = HDate.isHDate(date) ? (date as HDate) : new HDate(date);
732-
const hdStr = hd.toString();
733-
const yearMap = getHolidaysForYear_(hd.getFullYear());
734-
const events = yearMap.get(hdStr);
735-
// if il isn't a boolean return both diaspora + IL for day
736-
if (typeof il === 'undefined' || typeof events === 'undefined') {
737-
return events;
738-
}
739-
const myFilter = il ? observedInIsrael : observedInDiaspora;
740-
const filtered = events.filter(myFilter);
741-
return filtered;
709+
return getHolidaysOnDate(date, il);
742710
}
743711

744712
/**
@@ -802,10 +770,7 @@ export class HebrewCalendar {
802770
* 2 - Whole Hallel
803771
*/
804772
static hallel(hdate: HDate, il: boolean): number {
805-
const events = HebrewCalendar.getHolidaysForYearArray(
806-
hdate.getFullYear(),
807-
il
808-
);
773+
const events = getHolidaysForYearArray(hdate.getFullYear(), il);
809774
return hallel_(events, hdate);
810775
}
811776

@@ -834,7 +799,7 @@ export class HebrewCalendar {
834799
* @private
835800
*/
836801
function isChag(date: HDate, il: boolean): boolean {
837-
const events = HebrewCalendar.getHolidaysOnDate(date, il) || [];
802+
const events = getHolidaysOnDate(date, il) || [];
838803
const chag = events.filter(ev => ev.getFlags() & flags.CHAG);
839804
return chag.length !== 0;
840805
}

src/holidays.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,3 +425,58 @@ function getBirkatHaChama(year: number): number {
425425
}
426426
return 0;
427427
}
428+
429+
function observedInIsrael(ev: HolidayEvent): boolean {
430+
return ev.observedInIsrael();
431+
}
432+
433+
function observedInDiaspora(ev: HolidayEvent): boolean {
434+
return ev.observedInDiaspora();
435+
}
436+
437+
/**
438+
* Returns an array of Events on this date (or `undefined` if no events)
439+
* @param date Hebrew Date, Gregorian date, or absolute R.D. day number
440+
* @param [il] use the Israeli schedule for holidays
441+
*/
442+
export function getHolidaysOnDate(
443+
date: HDate | Date | number,
444+
il?: boolean
445+
): HolidayEvent[] | undefined {
446+
const hd = HDate.isHDate(date) ? (date as HDate) : new HDate(date);
447+
const hdStr = hd.toString();
448+
const yearMap = getHolidaysForYear_(hd.getFullYear());
449+
const events = yearMap.get(hdStr);
450+
// if il isn't a boolean return both diaspora + IL for day
451+
if (typeof il === 'undefined' || typeof events === 'undefined') {
452+
return events;
453+
}
454+
const myFilter = il ? observedInIsrael : observedInDiaspora;
455+
const filtered = events.filter(myFilter);
456+
return filtered;
457+
}
458+
459+
/**
460+
* Returns an array of holidays for the year
461+
* @param year Hebrew year
462+
* @param il use the Israeli schedule for holidays
463+
*/
464+
export function getHolidaysForYearArray(
465+
year: number,
466+
il: boolean
467+
): HolidayEvent[] {
468+
const yearMap = getHolidaysForYear_(year);
469+
const startAbs = HDate.hebrew2abs(year, TISHREI, 1);
470+
const endAbs = HDate.hebrew2abs(year + 1, TISHREI, 1) - 1;
471+
let events: HolidayEvent[] = [];
472+
const myFilter = il ? observedInIsrael : observedInDiaspora;
473+
for (let absDt = startAbs; absDt <= endAbs; absDt++) {
474+
const hd = new HDate(absDt);
475+
const holidays = yearMap.get(hd.toString());
476+
if (holidays) {
477+
const filtered: HolidayEvent[] = holidays.filter(myFilter);
478+
events = events.concat(filtered);
479+
}
480+
}
481+
return events;
482+
}

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export {
2828
RoshChodeshEvent,
2929
RoshHashanaEvent,
3030
} from './HolidayEvent';
31-
export {HolidayYearMap} from './holidays';
31+
export {HolidayYearMap, getHolidaysOnDate} from './holidays';
3232
export {MevarchimChodeshEvent} from './MevarchimChodeshEvent';
3333
export {holidayDesc} from './staticHolidays';
3434
export {DailyLearning} from './DailyLearning';

test/getHolidaysForYear.spec.js

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
import {HebrewCalendar} from '../src/hebcal';
1+
import {
2+
getHolidaysForYear_,
3+
getHolidaysForYearArray,
4+
} from '../src/holidays';
25
import {isoDateString} from '@hebcal/hdate';
36

47
jest.mock('quick-lru', () => {
@@ -14,7 +17,7 @@ function eventDateDesc(ev) {
1417
}
1518

1619
test('getHolidaysForYearArray-5771-diaspora', () => {
17-
const events = HebrewCalendar.getHolidaysForYearArray(5771, false).map(eventDateDesc);
20+
const events = getHolidaysForYearArray(5771, false).map(eventDateDesc);
1821
const expected = [
1922
{date: '2010-09-09', desc: 'Rosh Hashana 5771'},
2023
{date: '2010-09-10', desc: 'Rosh Hashana II'},
@@ -119,7 +122,7 @@ test('getHolidaysForYearArray-5771-diaspora', () => {
119122
});
120123

121124
test('getHolidaysForYearArray-5720-il', () => {
122-
const events = HebrewCalendar.getHolidaysForYearArray(5720, true).map(eventDateDesc);
125+
const events = getHolidaysForYearArray(5720, true).map(eventDateDesc);
123126
const expected = [
124127
{date: '1959-10-03', desc: 'Rosh Hashana 5720'},
125128
{date: '1959-10-04', desc: 'Rosh Hashana II'},
@@ -214,23 +217,23 @@ test('getHolidaysForYearArray-5720-il', () => {
214217
});
215218

216219
test('getHolidaysForYear-ce', () => {
217-
const map = HebrewCalendar.getHolidaysForYear(5888);
220+
const map = getHolidaysForYear_(5888);
218221
const rh = map.get('1 Tishrei 5888').map(eventDateDesc)[0];
219222
const pesach = map.get('15 Nisan 5888').map(eventDateDesc)[0];
220223
expect(rh).toEqual({date: '2127-09-08', desc: 'Rosh Hashana 5888'});
221224
expect(pesach).toEqual({date: '2128-04-15', desc: 'Pesach I'});
222225
});
223226

224227
test('getHolidaysForYear-bce', () => {
225-
const map = HebrewCalendar.getHolidaysForYear(3737);
228+
const map = getHolidaysForYear_(3737);
226229
const rh = map.get('1 Tishrei 3737').map(eventDateDesc)[0];
227230
const pesach = map.get('15 Nisan 3737').map(eventDateDesc)[0];
228231
expect(rh).toEqual({date: '-000024-09-11', desc: 'Rosh Hashana 3737'});
229232
expect(pesach).toEqual({date: '-000023-03-22', desc: 'Pesach I'});
230233
});
231234

232235
test('getHolidaysForYearArray-bce', () => {
233-
const events = HebrewCalendar.getHolidaysForYearArray(3759, false).slice(0, 15);
236+
const events = getHolidaysForYearArray(3759, false).slice(0, 15);
234237
const actual = events.map(eventDateDesc);
235238
const expected = [
236239
{date: '-000002-09-08', desc: 'Rosh Hashana 3759'},
@@ -255,7 +258,7 @@ test('getHolidaysForYearArray-bce', () => {
255258
test('Birkat Hachamah', () => {
256259
const actual = [];
257260
for (let year = 5650; year <= 5920; year++) {
258-
const events = HebrewCalendar.getHolidaysForYearArray(year, false);
261+
const events = getHolidaysForYearArray(year, false);
259262
const ev = events.find((ev) => ev.getDesc() === 'Birkat Hachamah');
260263
if (ev) {
261264
actual.push(year);
@@ -264,14 +267,19 @@ test('Birkat Hachamah', () => {
264267
const expected = [5657, 5685, 5713, 5741, 5769, 5797, 5825, 5853, 5881, 5909];
265268
expect(actual).toEqual(expected);
266269

267-
const events = HebrewCalendar.getHolidaysForYearArray(5965, false);
270+
const events = getHolidaysForYearArray(5965, false);
268271
const ev = events.find((ev) => ev.getDesc() === 'Birkat Hachamah');
269272
expect(typeof ev).toBe('object');
270273
expect(ev.getDate().toString()).toBe('19 Nisan 5965');
271274

272-
const events2 = HebrewCalendar.getHolidaysForYearArray(5993, false);
275+
const events2 = getHolidaysForYearArray(5993, false);
273276
const ev2 = events2.find((ev) => ev.getDesc() === 'Birkat Hachamah');
274277
expect(typeof ev2).toBe('object');
275278
expect(ev2.getDate().toString()).toBe('29 Adar II 5993');
276279
});
277280

281+
test('getHolidaysForYear-throw', () => {
282+
expect(() => {
283+
getHolidaysForYear_(-1);
284+
}).toThrow('Hebrew year -1 out of range 1-32658');
285+
});

test/getHolidaysOnDate.spec.ts

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import {HebrewCalendar} from '../src/hebcal';
21
import {HDate} from '@hebcal/hdate';
32
import {Event} from '../src/event';
3+
import {getHolidaysOnDate} from '../src/holidays';
44

55
jest.mock('quick-lru', () => {
66
return jest.fn().mockImplementation(() => {
@@ -20,7 +20,7 @@ test('getHolidaysOnDate', () => {
2020
for (const item of expected) {
2121
const dt = item.dt;
2222
const desc = item.desc;
23-
const ev = HebrewCalendar.getHolidaysOnDate(dt);
23+
const ev = getHolidaysOnDate(dt);
2424
if (typeof desc === 'undefined') {
2525
expect(ev).toBe(undefined);
2626
} else {
@@ -36,39 +36,39 @@ test('getHolidaysOnDate', () => {
3636
test('getHolidaysOnDate-il', () => {
3737
const dtShavuot1 = new Date(2021, 4, 17);
3838
const dtShavuot2 = new Date(2021, 4, 18);
39-
const events0 = HebrewCalendar.getHolidaysOnDate(dtShavuot1);
39+
const events0 = getHolidaysOnDate(dtShavuot1);
4040
expect(events0).toBeDefined();
4141
expect((events0 as Event[]).length).toBe(2);
4242

43-
const events1il = HebrewCalendar.getHolidaysOnDate(dtShavuot1, true);
43+
const events1il = getHolidaysOnDate(dtShavuot1, true);
4444
expect(events1il).toBeDefined();
4545
expect((events1il as Event[]).length).toBe(1);
4646
expect((events1il as Event[])[0].getDesc()).toBe('Shavuot');
4747

48-
const events1diaspora = HebrewCalendar.getHolidaysOnDate(dtShavuot1, false);
48+
const events1diaspora = getHolidaysOnDate(dtShavuot1, false);
4949
expect(events1diaspora).toBeDefined();
5050
expect((events1diaspora as Event[]).length).toBe(1);
5151
expect((events1diaspora as Event[])[0].getDesc()).toBe('Shavuot I');
5252

53-
const events2d = HebrewCalendar.getHolidaysOnDate(dtShavuot2, false);
53+
const events2d = getHolidaysOnDate(dtShavuot2, false);
5454
expect(events2d).toBeDefined();
5555
expect((events2d as Event[]).length).toBe(1);
5656
expect((events2d as Event[])[0].getDesc()).toBe('Shavuot II');
5757

58-
const events2il = HebrewCalendar.getHolidaysOnDate(dtShavuot2, true);
58+
const events2il = getHolidaysOnDate(dtShavuot2, true);
5959
expect(events2il).toBeDefined();
6060
expect((events2il as Event[]).length).toBe(0); // expected no Shavuot II in Israel
6161
});
6262

6363
test('getHolidaysOnDate-cacheHit', () => {
6464
const dt = new Date(2023, 11, 13);
6565
const hd = new HDate(dt);
66-
const ev1 = HebrewCalendar.getHolidaysOnDate(dt, false);
67-
const ev2 = HebrewCalendar.getHolidaysOnDate(hd, false);
68-
const ev3 = HebrewCalendar.getHolidaysOnDate(dt, true);
69-
const ev4 = HebrewCalendar.getHolidaysOnDate(hd, true);
70-
const ev5 = HebrewCalendar.getHolidaysOnDate(dt);
71-
const ev6 = HebrewCalendar.getHolidaysOnDate(hd);
66+
const ev1 = getHolidaysOnDate(dt, false);
67+
const ev2 = getHolidaysOnDate(hd, false);
68+
const ev3 = getHolidaysOnDate(dt, true);
69+
const ev4 = getHolidaysOnDate(hd, true);
70+
const ev5 = getHolidaysOnDate(dt);
71+
const ev6 = getHolidaysOnDate(hd);
7272
expect(ev1).toEqual(ev2);
7373
expect(ev1).toEqual(ev3);
7474
expect(ev1).toEqual(ev4);
@@ -78,16 +78,16 @@ test('getHolidaysOnDate-cacheHit', () => {
7878

7979
test('getHolidaysOnDate-neg-cacheHit', () => {
8080
const hd = new HDate(3, 'Cheshvan', 5771);
81-
const ev1 = HebrewCalendar.getHolidaysOnDate(hd, false);
82-
const ev2 = HebrewCalendar.getHolidaysOnDate(hd, false);
83-
const ev3 = HebrewCalendar.getHolidaysOnDate(hd.greg(), false);
81+
const ev1 = getHolidaysOnDate(hd, false);
82+
const ev2 = getHolidaysOnDate(hd, false);
83+
const ev3 = getHolidaysOnDate(hd.greg(), false);
8484
expect(ev1).toBe(undefined);
8585
expect(ev2).toBe(undefined);
8686
expect(ev3).toBe(undefined);
8787
});
8888

8989
test('getHolidaysOnDate does not include Mevarchim Chodesh', () => {
9090
// {date: '2011-05-28', desc: 'Shabbat Mevarchim Chodesh Sivan'}
91-
const events = HebrewCalendar.getHolidaysOnDate(new Date(2011, 4, 28), false);
91+
const events = getHolidaysOnDate(new Date(2011, 4, 28), false);
9292
expect(events).toBe(undefined);
9393
});

test/hallel.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {HDate, months} from '@hebcal/hdate';
2-
import {HebrewCalendar} from '../src/hebcal';
2+
import {getHolidaysForYearArray} from '../src/holidays';
33
import {hallel_} from '../src/hallel';
44

55
jest.mock('quick-lru', () => {
@@ -9,7 +9,7 @@ jest.mock('quick-lru', () => {
99
});
1010

1111
test('hallel', () => {
12-
const ev1 = HebrewCalendar.getHolidaysForYearArray(5781, false);
12+
const ev1 = getHolidaysForYearArray(5781, false);
1313
expect(hallel_(ev1, new HDate(14, months.NISAN, 5781))).toBe(0);
1414
expect(hallel_(ev1, new HDate(15, months.NISAN, 5781))).toBe(2);
1515
expect(hallel_(ev1, new HDate(16, months.NISAN, 5781))).toBe(2);
@@ -19,7 +19,7 @@ test('hallel', () => {
1919
expect(hallel_(ev1, new HDate(29, months.KISLEV, 5781))).toBe(2);
2020
expect(hallel_(ev1, new HDate(21, months.KISLEV, 5781))).toBe(0);
2121

22-
const ev2 = HebrewCalendar.getHolidaysForYearArray(5781, true);
22+
const ev2 = getHolidaysForYearArray(5781, true);
2323
expect(hallel_(ev2, new HDate(17, months.NISAN, 5781))).toBe(1);
2424
expect(hallel_(ev2, new HDate(28, months.NISAN, 5781))).toBe(0);
2525
expect(hallel_(ev2, new HDate(30, months.NISAN, 5781))).toBe(1);

test/hebcal.spec.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -476,12 +476,6 @@ test('year0', () => {
476476
expect(events.length).toBe(82);
477477
});
478478

479-
test('getHolidaysForYear-throw', () => {
480-
expect(() => {
481-
HebrewCalendar.getHolidaysForYear(-1);
482-
}).toThrow('Hebrew year -1 out of range 1-32658');
483-
});
484-
485479
test('version', () => {
486480
const version = HebrewCalendar.version();
487481
expect(version.substring(0, version.indexOf('.'))).toBe('5');

0 commit comments

Comments
 (0)