hebcal / hebcal-es6

perpetual Jewish Calendar with holidays, Shabbat and holiday candle lighting and havdalah times, Torah readings, and more
https://hebcal.github.io/api/core/
GNU General Public License v2.0
97 stars 14 forks source link

Why does Chanukah start at 24th Kislev? #386

Open PupaRebbe opened 7 months ago

PupaRebbe commented 7 months ago
  1. This code shows "Chanukah: 1 Candle" for the 24th of Kislev, isn't Chanukah starting at the 25th?
  2. Is there any way to filter out the holidays that aren't relevant to me like Chag HaBanot, Rosh Hashana LaBehemot etc.? Thanks
    const events = HebrewCalendar.calendar({
    year: 5784,
    isHebrewYear: true,
    noModern: true,
    mask: flags.MINOR_HOLIDAY
    });
mjradwin commented 7 months ago
  1. Chanukah starts on the 25th of Kislev. Instead of listing "Erev Chanukah" on the 24th, Hebcal lists the event as "Chanukah: 1 Candle". Candle-lighting for the first night of Chanukah occurs on the previous Gregorian evening, and this decision was made 30+ years ago to improve observance for Hebcal users who might otherwise be confused about how many candles to light each evening.

  2. Before you filter out all minor holidays, please note that there is some subjectivity and disagreement about what constitutes a minor holiday. For example, both Purim and Chanukah are considered minor holidays when it comes to halacha. They are flagged as such in Hebcal.

There are several ways to handle this. You can use the mask feature, but if you do so, you will want to select the inverse of what you listed in the code example above. That mask feature, if specified, is a bitmask of what to include in the results, not exclude. So to use mask the way you intend, you'll probably need to something verbose like the following:

const mask = flags.ROSH_CHODESH | flags.YOM_TOV_ENDS | flags.MINOR_FAST |
  flags.SPECIAL_SHABBAT | flags.MODERN_HOLIDAY | flags.MAJOR_FAST |
  flags.EREV | flags.CHOL_HAMOED |
  flags.LIGHT_CANDLES | flags.LIGHT_CANDLES_TZEIS | flags.CHANUKAH_CANDLES;

Another way to handle it would be to do something like this:

  // generates 83 events
  const events0 = HebrewCalendar.calendar({
    year: 5784,
    isHebrewYear: true,
    noModern: true,
  });

  // reduces to 62 events
  // note that Chag HaBanot, Rosh Hashana LaBehemot, Purim and Chanukah are all filtered out
  const events = events0.filter((ev) => ! (ev.getFlags() & flags.MINOR_HOLIDAY));

In addition to noModern, which you have used above to pre-filter some holidays, the documentation also explains the options noRoshChodesh, noMinorFast, or noSpecialShabbat.

mjradwin commented 7 months ago

I'll add that if you want to filter most minor holidays but include Purim and Chanukah, you can also do something like this:

  const events2 = events0.filter((ev) => {
    const bn = ev.basename();
    if (bn === 'Purim' || bn === 'Chanukah') {
      return true;
    } else {
      return ! (ev.getFlags() & flags.MINOR_HOLIDAY);
    }
  });

Feel free to follow that example to get more fine-grained control over which holidays are included and which aren't.

PupaRebbe commented 3 months ago

I noticed that the event.getCategories() function returns ["holiday", "major"] for Chanukah

const events = HebrewCalendar.calendar({
    start: new HDate(25, months.KISLEV, 5784),
    end: new HDate(26, months.KISLEV, 5784)
});
console.log(events[0].getCategories());
mjradwin commented 3 months ago

Looks like this is a bug. We'll investigate and unless we find a compelling reason, we expect to change it so it matches the expected ["holiday", "minor"]