Hebcal Es6
perpetual Jewish Calendar with holidays, Shabbat and holiday candle lighting and havdalah times, Torah readings, and more
Install / Use
npx skills add hebcal/hebcal-es6Installs into whichever agent you are using.
README
@hebcal/core
Hebcal is a perpetual Jewish Calendar. This library converts between Hebrew and Gregorian dates, and generates lists of Jewish holidays for any year (past, present or future). Shabbat and holiday candle lighting and havdalah times are approximated based on location. Torah readings (Parashat HaShavua), Daf Yomi, and counting of the Omer can also be specified. Hebcal also includes algorithms to calculate yahrzeits, birthdays and anniversaries.
@hebcal/core targets both browser-based JavaScript and server-side Node.js.
Most work starts with the calendar()
function and the HDate class.
Nearly everything is available as a standalone function — calendar(),
getHolidaysOnDate(), getSedra(), tachanun(), reformatTimeStr() — and the
examples here use that form, since importing only what you need is what lets a
bundler drop the rest. The same functions are also reachable as static methods on
HebrewCalendar.
Yahrzeits and birthdays are standalone functions too, but they live in
@hebcal/hdate rather than here — import yahrzeit() and
birthdayOrAnniversary() from there directly.
HebrewCalendar.getYahrzeit() and .getBirthdayOrAnniversary() are thin
wrappers over them. A few odds and ends remain class-only:
eruvTavshilin(), hallel() and getHolidaysForYear().
Installation
npm install @hebcal/core
Synopsis
import {calendar, Location} from '@hebcal/core';
const events = calendar({
year: 1981,
isHebrewYear: false,
candlelighting: true,
location: Location.lookup('San Francisco'),
sedrot: true,
omer: true,
});
for (const ev of events) {
const hd = ev.getDate();
const date = hd.greg();
console.log(date.toLocaleDateString(), ev.render('en'), hd.toString());
}
Events and flags
Everything calendar() returns is an Event:
a Hebrew date, a description, a flags bitmask, and optional extras. Subclasses add
detail — HolidayEvent, ParshaEvent, OmerEvent, CandleLightingEvent and
HavdalahEvent (both TimedEvents, carrying an eventTime), MoladEvent,
HebrewDateEvent, and others.
Rather than testing instanceof, classify events with flags:
import {calendar, flags} from '@hebcal/core';
const events = calendar({year: 5784, isHebrewYear: true});
for (const ev of events) {
if (ev.getFlags() & flags.MAJOR_FAST) {
console.log('fast day:', ev.render('en'));
}
}
You can also push the filter down into generation, which is cheaper than filtering
afterwards, via options.mask:
const roshChodesh = calendar({
year: 5784,
isHebrewYear: true,
mask: flags.ROSH_CHODESH,
});
Event.getCategories() gives a coarser, string-based classification
(['holiday', 'major', 'fast']) that is handy for CSS classes or grouping.
See the flags API docs
for the full list.
Looking up a single date
calendar() is built for generating a range. When you only need to know what
falls on one day, getHolidaysOnDate() is much more direct — it reads from an
internally cached per-year map instead of running the full generator:
import {getHolidaysOnDate, HDate, months} from '@hebcal/core';
const events = getHolidaysOnDate(new HDate(15, months.NISAN, 5784), false);
console.log(events?.map(ev => ev.getDesc())); // ['Pesach I']
Three things to know:
- It returns
undefined— not an empty array — when nothing falls on that date, so useevents?.map(...)or check before indexing. - The
ilargument is optional, and omitting it is not the same as passingfalse. Withilomitted you get both the Israel and Diaspora events for that date, unfiltered; passtrueorfalseto get one schedule. - It accepts an
HDate, aDate, or an absolute R.D. day number.
It returns only holidays. Candle-lighting times, Torah readings and Omer days come
from calendar(), which is what options.candlelighting, options.sedrot and
options.omer drive.
Daily learning (Daf Yomi and friends)
@hebcal/core ships no learning schedules itself. DailyLearning is a plug-in
registry; the schedules live in the separate
@hebcal/learning package, which
registers them by calling DailyLearning.addCalendar() when you import it. This
keeps the daily-study tables — which are large and grow as new cycles are added —
out of the core bundle for the many users who don't need them.
Import @hebcal/learning once for its side effects, then request calendars through
options.dailyLearning:
import '@hebcal/learning';
import {calendar, flags} from '@hebcal/core';
const events = calendar({
year: 5784,
isHebrewYear: true,
noHolidays: true,
dailyLearning: {dafYomi: true},
});
for (const ev of events) {
if (ev.getFlags() & flags.DAF_YOMI) {
console.log(ev.getDate().toString(), ev.render('en'));
}
}
Daf Yomi (Babylonian Talmud) is by far the most widely used. @hebcal/learning also
provides Yerushalmi Yomi, Mishna Yomi, Nach Yomi, Daf Weekly, Chofetz Chaim, Rambam,
929 and more. Most take true; yerushalmi takes a number selecting the edition
(1 for Vilna, 2 for Schottenstein):
dailyLearning: {dafYomi: true, mishnaYomi: true, yerushalmi: 1}
To query a single day without generating a calendar, use DailyLearning.lookup():
import '@hebcal/learning';
import {DailyLearning, HDate, months} from '@hebcal/core';
const ev = DailyLearning.lookup(
'dafYomi',
new HDate(15, months.CHESHVAN, 5784),
false
);
console.log(ev?.render('en')); // 'Daf Yomi: Kiddushin 78'
DailyLearning.getCalendars() returns the authoritative list of what the installed
version of @hebcal/learning actually registered; has() and getStartDate() report
whether a given calendar is available and from what date. You can register your own
schedule with addCalendar() — the same entry point @hebcal/learning uses.
Candle lighting, Havdalah, and fast times
Set options.candlelighting = true and supply an options.location to get timed
events. Times are computed from latitude and longitude via NOAA solar equations. If
you ever have any doubts about Hebcal's times, consult your local halachic authority —
and note that coordinates above the Arctic or below the Antarctic circle are
guaranteed to be wrong.
import {calendar, Location, flags} from '@hebcal/core';
const events = calendar({
year: 2024,
candlelighting: true,
location: Location.lookup('Jerusalem'),
});
for (const ev of events) {
if (ev.getFlags() & flags.LIGHT_CANDLES) {
console.log(ev.getDate().toString(), ev.eventTimeStr); // '24 Tevet 5784' '16:08'
}
}
Candle lighting defaults to 18 minutes before sunset in the Diaspora and 20
minutes in Israel, with 40 minutes for Jerusalem and 30 for Haifa and Zikhron
Ya'akov. Override with options.candleLightingMins.
Havdalah defaults to Tzeit Hakochavim — nightfall, when 3 small stars are visible — calculated at 8.5° of solar depression. Two mutually exclusive overrides:
options.havdalahDeg— a different solar depression angle (7.083° is the common alternative, for 3 medium-sized stars). Set to0to suppress Havdalah times.options.havdalahMins— a fixed number of minutes after sunset instead (42, 50 and 72 are typical). Set to0to suppress Havdalah times.
Minor fasts begin at Alot HaShachar (16.1° in the morning). They end at 7.083°
in the Diaspora, or 15 minutes after sunset in Israel (Rabbi Deblitzky's practice).
Override with options.fastEndDeg or options.fastEndMins — again mutually
exclusive. When a minor fast falls on a Friday, the end time is suppressed, because
Shabbat begins before nightfall.
Tish'a B'Av does not follow those rules: it begins at sunset the previous day and
always ends at 6.45° (Rabbi Yechiel Michel Tucazinsky), ignoring fastEndDeg and
fastEndMins.
Chanukah candle-lighting, also generated when candlelighting and location
are set, is at Bein HaShmashos (13.5 minutes before 7.083°) on weekdays, regular
candle-lighting time on Friday, and regular Havdalah time on Saturday night.
Set options.useElevation = true to factor a location's elevation into sunrise and
sunset. Note that degree-based zmanim estimate the amount of light in the sky and
so are unaffected by elevation by design; chatzot is also always computed at sea
level.
For zmanim outside the calendar-generation flow, use the
Zmanim class directly.
Yahrzeits, birthdays, and anniversaries
These are two different calculations, not one function with a flag, because the customs genuinely differ. Both follow "Calendrical Calculations" by Reingold and Dershowitz.
Both live in @hebcal/hdate; HebrewCalendar exposes them as wrappers for
convenience.
import {birthdayOrAnniversary, yahrzeit} from '@hebcal/hdate';
const dt = new Date(2014, 2, 2); // 30 Adar I 5774
birthdayOrAnniversary(5785, dt)?.toString(); // '1 Nisan 5785'
yahrzeit(5785, dt)?.toString(); // '30 Sh'vat 5785'
The short version: a birthday moves forward, a yahrzeit moves back. When the original day doesn't exist in the target year, a birthday is postponed to the first of the following month, whereas a yahrzeit is observed on the day before that — so in the example above the two land a month apart.
A yahrzeit has one more wrinkle: for a death on 30 Marcheshvan or 30 Kislev, the date in later years
Related Skills
node-connect
385.5kDiagnose OpenClaw Android, iOS, or macOS node pairing, QR/setup code, route, auth, and connection failures.
blender-python-addon
40.5kBlender Python add-on rules for operators, panels, properties, registration, testing, and API-safe scripting
flutter-development-guidelines-cursorrules-prompt-file
40.5kCursor rules for Flutter development with MVVM architecture, Riverpod state management, Material widgets, and Dart style guidelines.
commit-push-pr
140.6kCommit, push, and open a PR
