@hebcal/leyning
Version:
Torah Reading API for Parashat HaShavua and holidays
1,310 lines (1,288 loc) • 147 kB
JavaScript
/*! @hebcal/leyning v9.5.4 */
var hebcal__leyning = (function (exports, locale, event, holidays, sedra, ParshaEvent) {
'use strict';
var poHe$1 = { "headers": { "plural-forms": "nplurals=2; plural=(n > 1);", "language": "he_IL" }, "contexts": { "": { "Shabbat Machar Chodesh": ["שַׁבָּת מָחָר חוֹדֶשׁ"], "Shabbat Rosh Chodesh": ["שַׁבָּת רֹאשׁ חוֹדֶשׁ"], "Pesach I (on Shabbat)": ["פֶּסַח יוֹם א׳ (בְּשַׁבָּת)"], "Pesach Chol ha-Moed Day 1": ["פֶּסַח חֹל הַמּוֹעֵד יוֹם א׳"], "Pesach Chol ha-Moed Day 2": ["פֶּסַח חֹל הַמּוֹעֵד יוֹם ב׳"], "Pesach Chol ha-Moed Day 2 on Sunday": ["פֶּסַח חֹל הַמּוֹעֵד יוֹם ב׳ (בְּיוֹם רִאשׁוֹן)"], "Pesach Chol ha-Moed Day 3": ["פֶּסַח חֹל הַמּוֹעֵד יוֹם ג׳"], "Pesach Chol ha-Moed Day 3 on Monday": ["פֶּסַח חֹל הַמּוֹעֵד יוֹם ג׳ (בְּיוֹם שֵׁנִי)"], "Pesach Chol ha-Moed Day 4": ["פֶּסַח חֹל הַמּוֹעֵד יוֹם ד׳"], "Pesach Chol ha-Moed Day 5": ["פֶּסַח חֹל הַמּוֹעֵד יוֹם ה׳"], "Pesach VII (on Shabbat)": ["פֶּסַח ז׳ (בְּשַׁבָּת)"], "Pesach VIII (on Shabbat)": ["פֶּסַח ח׳ (בְּשַׁבָּת)"], "Shavuot II (on Shabbat)": ["שָׁבוּעוֹת יוֹם ב׳ (בְּשַׁבָּת)"], "Fast Day (Morning)": ["תַּעֲנִית (שַׁחֲרִית)"], "Fast Day (Afternoon)": ["תַּעֲנִית (מִנְחָה)"], "Rosh Hashana I (on Shabbat)": ["רֹאשׁ הַשָּׁנָה א׳ (בְּשַׁבָּת)"], "Yom Kippur (on Shabbat)": ["יוֹם כִּפּוּר (בְּשַׁבָּת)"], "Yom Kippur (Mincha, Traditional)": ["יוֹם כִּפּוּר מִנְחָה"], "Yom Kippur (Mincha, Alternate)": ["יוֹם כִּפּוּר מִנְחָה"], "Sukkot I (on Shabbat)": ["סֻכּוֹת יוֹם א׳ (בְּשַׁבָּת)"], "Sukkot Chol ha-Moed Day 1": ["סֻכּוֹת חֹל הַמּוֹעֵד יוֹם א׳"], "Sukkot Chol ha-Moed Day 2": ["סֻכּוֹת חֹל הַמּוֹעֵד יוֹם ב׳"], "Sukkot Chol ha-Moed Day 3": ["סֻכּוֹת חֹל הַמּוֹעֵד יוֹם ג׳"], "Sukkot Chol ha-Moed Day 4": ["סֻכּוֹת חֹל הַמּוֹעֵד יוֹם ד׳"], "Sukkot Chol ha-Moed Day 5": ["סֻכּוֹת חֹל הַמּוֹעֵד יוֹם ה׳"], "Sukkot Final Day (Hoshana Raba)": ["סֻכּוֹת ז׳ (הוֹשַׁעְנָא רַבָּה)"], "Shmini Atzeret (on Shabbat)": ["שְׁמִינִי עֲצֶרֶת (בְּשַׁבָּת)"], "Simchat Torah (on Shabbat)": ["שִׂמְחַת תּוֹרָה (בְּשַׁבָּת)"], "Chanukah Day 1": ["חֲנוּכָּה יוֹם א׳"], "Chanukah Day 2": ["חֲנוּכָּה יוֹם ב׳"], "Chanukah Day 3": ["חֲנוּכָּה יוֹם ג׳"], "Chanukah Day 4": ["חֲנוּכָּה יוֹם ד׳"], "Chanukah Day 5": ["חֲנוּכָּה יוֹם ה׳"], "Chanukah Day 6": ["חֲנוּכָּה יוֹם ו׳"], "Chanukah Day 7": ["חֲנוּכָּה יוֹם ז׳"], "Chanukah Day 7 (on Rosh Chodesh)": ["חֲנוּכָּה יוֹם ז׳ (רֹאשׁ חוֹדֶשׁ)"], "Chanukah Day 8": ["חֲנוּכָּה יוֹם ח׳"], "Chanukah Day 1 (on Shabbat)": ["חֲנוּכָּה יוֹם א׳ (בְּשַׁבָּת)"], "Chanukah Day 2 (on Shabbat)": ["חֲנוּכָּה יוֹם ב׳ (בְּשַׁבָּת)"], "Chanukah Day 3 (on Shabbat)": ["חֲנוּכָּה יוֹם ג׳ (בְּשַׁבָּת)"], "Chanukah Day 4 (on Shabbat)": ["חֲנוּכָּה יוֹם ד׳ (בְּשַׁבָּת)"], "Chanukah Day 5 (on Shabbat)": ["חֲנוּכָּה יוֹם ה׳ (בְּשַׁבָּת)"], "Chanukah Day 7 (on Shabbat)": ["חֲנוּכָּה יוֹם ז׳ (בְּשַׁבָּת)"], "Chanukah Day 8 (on Shabbat)": ["חֲנוּכָּה יוֹם ח׳ (בְּשַׁבָּת)"], "Shabbat Rosh Chodesh Chanukah": ["שַׁבָּת רֹאשׁ חוֹדֶשׁ חֲנוּכָּה"], "Shushan Purim (on Shabbat)": ["שׁוּשַׁן פּוּרִים (בְּשַׁבָּת)"], "Yom Kippur (Mincha)": ["יוֹם כִּפּוּר (מִנְחָה)"], "Tish'a B'Av (Mincha)": ["תִּשְׁעָה בְּאָב (מִנְחָה)"], "Asara B'Tevet (Mincha)": ["עֲשָׂרָה בְּטֵבֵת (מִנְחָה)"], "Ta'anit Bechorot (Mincha)": ["תַּעֲנִית בְּכוֹרוֹת (מִנְחָה)"], "Ta'anit Esther (Mincha)": ["תַּעֲנִית אֶסְתֵּר (מִנְחָה)"], "Tzom Gedaliah (Mincha)": ["צוֹם גְּדַלְיָה (מִנְחָה)"], "Tzom Tammuz (Mincha)": ["צוֹם י״ז בְּתַמּוּז (מִנְחָה)"], "Genesis": ["בְּרֵאשִׁית"], "Exodus": ["שְׁמוֹת"], "Leviticus": ["וַיִּקְרָא"], "Numbers": ["בְּמִדְבַּר"], "Deuteronomy": ["דְּבָרִים"], "Joshua": ["יְהוֹשֻׁעַ"], "Judges": ["שׁוֹפְטִים"], "I Samuel": ["שְׁמוּאֵל א"], "II Samuel": ["שְׁמוּאֵל ב"], "I Kings": ["מְלָכִים א"], "II Kings": ["מְלָכִים ב"], "Isaiah": ["יְשַׁעְיָהוּ"], "Jeremiah": ["יִרְמְיָהוּ"], "Ezekiel": ["יְחֶזְקֵאל"], "Hosea": ["הוֹשֵׁעַ"], "Joel": ["יוֹאֵל"], "Amos": ["עָמוֹס"], "Obadiah": ["עוֹבַדְיָה"], "Jonah": ["יוֹנָה"], "Micah": ["מִיכָה"], "Nachum": ["נַחוּם"], "Habakkuk": ["חֲבַקּוּק"], "Zephaniah": ["צְפַנְיָה"], "Haggai": ["חַגַּי"], "Zechariah": ["זְכַרְיָה"], "Malachi": ["מַלְאָכִי"], "Song of Songs": ["שִׁיר הַשִּׁירִים"], "Ruth": ["רוּת"], "Lamentations": ["אֵיכָה"], "Ecclesiastes": ["קֹהֶלֶת"], "Esther": ["אֶסְתֵּר"], "Pinchas occurring after 17 Tammuz": ["פִּינְחָס מתרחש לאחר יז׳ בְּתַמּוּז"], "Kedoshim following Special Shabbat": ["קְדֹשִׁים לאחר שַׁבָּת מיוחדת"], "Masei on Shabbat Rosh Chodesh": ["מַסְעֵי בְּשַׁבָּת רֹאשׁ חוֹדֶשׁ"], "Matot-Masei on Shabbat Rosh Chodesh": ["מַטּוֹת־מַסְעֵי בְּשַׁבָּת רֹאשׁ חוֹדֶשׁ"], "Ki Teitzei with 3rd Haftarah of Consolation": ["כִּי־תֵצֵא עם הַפְטָרָה שְׁלִישִׁית שֶׁל נֶחָמָה"], "Shabbat HaChodesh (on Rosh Chodesh)": ["שַׁבָּת הַחוֹדֶשׁ (בְּרֹאשׁ חוֹדֶשׁ)"], "Shabbat Shekalim (on Rosh Chodesh)": ["שַׁבָּת שְׁקָלִים (רֹאשׁ חוֹדֶשׁ)"], "Shabbat Shuva (with Vayeilech)": ["שַׁבַּת שׁוּבָה (עם וַיֵּלֶךְ)"], "Shabbat Shuva (with Ha'azinu)": ["שַׁבַּת שׁוּבָה (עם הַאֲזִינוּ)"] } } };
var poAshkenazi$1 = { "headers": { "plural-forms": "nplurals=2; plural=(n > 1);", "language": "en_CA@ashkenazi" }, "contexts": { "": { "Shabbat Machar Chodesh": ["Shabbos Machar Chodesh"], "Shabbat Rosh Chodesh": ["Shabbos Rosh Chodesh"], "Pesach I (on Shabbat)": ["Pesach I (on Shabbos)"], "Pesach Shabbat Chol ha-Moed": ["Pesach Shabbos Chol ha-Moed"], "Pesach VII (on Shabbat)": ["Pesach VII (on Shabbos)"], "Pesach VIII (on Shabbat)": ["Pesach VIII (on Shabbos)"], "Shavuot II (on Shabbat)": ["Shavuos II (on Shabbos)"], "Rosh Hashana I (on Shabbat)": ["Rosh Hashana I (on Shabbos)"], "Yom Kippur (on Shabbat)": ["Yom Kippur (on Shabbos)"], "Sukkot I (on Shabbat)": ["Sukkos I (on Shabbos)"], "Sukkot Chol ha-Moed Day 1": ["Sukkos Chol ha-Moed Day 1"], "Sukkot Chol ha-Moed Day 2": ["Sukkos Chol ha-Moed Day 2"], "Sukkot Chol ha-Moed Day 3": ["Sukkos Chol ha-Moed Day 3"], "Sukkot Chol ha-Moed Day 4": ["Sukkos Chol ha-Moed Day 4"], "Sukkot Chol ha-Moed Day 5": ["Sukkos Chol ha-Moed Day 5"], "Sukkot Shabbat Chol ha-Moed": ["Sukkos Shabbos Chol ha-Moed"], "Sukkot Final Day (Hoshana Raba)": ["Sukkos Final Day (Hoshana Raba)"], "Shmini Atzeret (on Shabbat)": ["Shmini Atzeres (on Shabbos)"], "Chanukah Day 1 (on Shabbat)": ["Chanukah Day 1 (on Shabbos)"], "Chanukah Day 2 (on Shabbat)": ["Chanukah Day 2 (on Shabbos)"], "Chanukah Day 3 (on Shabbat)": ["Chanukah Day 3 (on Shabbos)"], "Chanukah Day 4 (on Shabbat)": ["Chanukah Day 4 (on Shabbos)"], "Chanukah Day 5 (on Shabbat)": ["Chanukah Day 5 (on Shabbos)"], "Chanukah Day 7 (on Shabbat)": ["Chanukah Day 7 (on Shabbos)"], "Chanukah Day 8 (on Shabbat)": ["Chanukah Day 8 (on Shabbos)"], "Shabbat Rosh Chodesh Chanukah": ["Shabbos Rosh Chodesh Chanukah"], "Asara B'Tevet (Mincha)": ["Asara B’Teves (Mincha)"], "Ta'anit Bechorot (Mincha)": ["Ta’anis Bechoros (Mincha)"], "Ta'anit Esther (Mincha)": ["Ta’anis Esther (Mincha)"] } } };
var noNikudOverride = { "headers": { "plural-forms": "nplurals=2; plural=(n != 1);", "language": "he-x-NoNikud" }, "contexts": { "": { "Pesach Chol ha-Moed Day 1": ["פסח חול המועד יום א׳"], "Pesach Chol ha-Moed Day 2": ["פסח חול המועד יום ב׳"], "Pesach Chol ha-Moed Day 2 on Sunday": ["פסח חול המועד יום ב׳ (ביום ראשון)"], "Pesach Chol ha-Moed Day 3": ["פסח חול המועד יום ג׳"], "Pesach Chol ha-Moed Day 3 on Monday": ["פסח חול המועד יום ג׳ (ביום שני)"], "Pesach Chol ha-Moed Day 4": ["פסח חול המועד יום ד׳"], "Pesach Chol ha-Moed Day 5": ["פסח חול המועד יום ה׳"], "Sukkot Chol ha-Moed Day 1": ["סוכות חול המועד יום א׳"], "Sukkot Chol ha-Moed Day 2": ["סוכות חול המועד יום ב׳"], "Sukkot Chol ha-Moed Day 3": ["סוכות חול המועד יום ג׳"], "Sukkot Chol ha-Moed Day 4": ["סוכות חול המועד יום ד׳"], "Sukkot Chol ha-Moed Day 5": ["סוכות חול המועד יום ה׳"], "Sukkot I (on Shabbat)": ["סוכות יום א׳ (בשבת)"], "Sukkot Final Day (Hoshana Raba)": ["סוכות ז׳ (הושענא רבה)"], "Yom Kippur (on Shabbat)": ["יום כיפור (בשבת)"], "Yom Kippur (Mincha, Traditional)": ["יום כיפור מנחה"], "Yom Kippur (Mincha, Alternate)": ["יום כיפור מנחה"], "Yom Kippur (Mincha)": ["יום כיפור (מנחה)"] } } };
locale.Locale.addTranslations('ashkenazi', poAshkenazi$1);
locale.Locale.addTranslations('he', poHe$1);
/* Hebrew without nikkud */
const poHeNoNikud$1 = locale.Locale.copyLocaleNoNikud(poHe$1);
locale.Locale.addTranslations('he-x-NoNikud', poHeNoNikud$1);
locale.Locale.addTranslations('he-x-NoNikud', noNikudOverride);
/*! @hebcal/hdate v0.22.0, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
/** @private */
const lengths = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
/** @private */
const monthLengths = [lengths, lengths.slice()];
monthLengths[1][2] = 29;
/**
* @private
*/
function mod$1(x, y) {
return x - y * Math.floor(x / y);
}
/**
* @private
*/
function quotient(x, y) {
return Math.floor(x / y);
}
/**
* @private
* @param abs - R.D. number of days
*/
function yearFromFixed(abs) {
const l0 = abs - 1;
const n400 = quotient(l0, 146097);
const d1 = mod$1(l0, 146097);
const n100 = quotient(d1, 36524);
const d2 = mod$1(d1, 36524);
const n4 = quotient(d2, 1461);
const d3 = mod$1(d2, 1461);
const n1 = quotient(d3, 365);
const year = 400 * n400 + 100 * n100 + 4 * n4 + n1;
return n100 !== 4 && n1 !== 4 ? year + 1 : year;
}
/*
const ABS_14SEP1752 = 639797;
const ABS_2SEP1752 = 639785;
*/
/*
* Formerly in namespace, now top-level
*/
/**
* Returns true if the Gregorian year is a leap year
* @param year Gregorian year
*/
function isGregLeapYear(year) {
return !(year % 4) && (!!(year % 100) || !(year % 400));
}
/**
* Number of days in the Gregorian month for given year
* @param month Gregorian month (1=January, 12=December)
* @param year Gregorian year
*/
function daysInGregMonth(month, year) {
// 1 based months
return monthLengths[+isGregLeapYear(year)][month];
}
/**
* Returns true if the object is a Javascript Date
*/
function isDate(obj) {
// eslint-disable-next-line no-prototype-builtins
return typeof obj === 'object' && Date.prototype.isPrototypeOf(obj);
}
/**
* @private
* @param year
* @param month (1-12)
* @param day (1-31)
*/
function toFixed(year, month, day) {
const py = year - 1;
return (365 * py +
quotient(py, 4) -
quotient(py, 100) +
quotient(py, 400) +
quotient(367 * month - 362, 12) +
(month <= 2 ? 0 : isGregLeapYear(year) ? -1 : -2) +
day);
}
/**
* Converts Gregorian date to absolute R.D. (Rata Die) days
* @param date Gregorian date
*/
function greg2abs(date) {
if (!isDate(date)) {
throw new TypeError(`not a Date: ${date}`);
}
else if (isNaN(date.getTime())) {
throw new RangeError('Invalid Date');
}
const abs = toFixed(date.getFullYear(), date.getMonth() + 1, date.getDate());
/*
if (abs < ABS_14SEP1752 && abs > ABS_2SEP1752) {
throw new RangeError(`Invalid Date: ${date}`);
}
*/
return abs;
}
/**
* Converts from Rata Die (R.D. number) to Gregorian date.
* See the footnote on page 384 of ``Calendrical Calculations, Part II:
* Three Historical Calendars'' by E. M. Reingold, N. Dershowitz, and S. M.
* Clamen, Software--Practice and Experience, Volume 23, Number 4
* (April, 1993), pages 383-404 for an explanation.
*
* Note that this function returns the daytime portion of the date.
* For example, the 15th of Cheshvan 5769 began at sundown on
* 12 November 2008 and continues through 13 November 2008. This
* function would return only the date 13 November 2008.
* @param abs - R.D. number of days
* @example
* const abs = hebrew2abs(5769, months.CHESHVAN, 15);
* const date = abs2greg(abs); // 13 November 2008
* const year = date.getFullYear(); // 2008
* const monthNum = date.getMonth() + 1; // 11
* const day = date.getDate(); // 13
*/
function abs2greg(abs) {
if (typeof abs !== 'number' || isNaN(abs)) {
throw new TypeError(`not a Number: ${abs}`);
}
abs = Math.trunc(abs);
/*
if (abs < ABS_14SEP1752 && abs > ABS_2SEP1752) {
throw new RangeError(`Invalid Date: ${abs}`);
}
*/
const year = yearFromFixed(abs);
const priorDays = abs - toFixed(year, 1, 1);
const correction = abs < toFixed(year, 3, 1) ? 0 : isGregLeapYear(year) ? 1 : 2;
const month = quotient(12 * (priorDays + correction) + 373, 367);
const day = abs - toFixed(year, month, 1) + 1;
const dt = new Date(year, month - 1, day);
if (year < 100 && year >= 0) {
dt.setFullYear(year);
}
return dt;
}
/*! @hebcal/hdate v0.22.0, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
/* eslint-disable @typescript-eslint/no-namespace */
/**
* Gregorian date helper functions
*/
var greg;
(function (greg) {
})(greg || (greg = {}));
greg.abs2greg = abs2greg;
greg.daysInMonth = daysInGregMonth;
greg.greg2abs = greg2abs;
greg.isDate = isDate;
greg.isLeapYear = isGregLeapYear;
/*! @hebcal/hdate v0.22.0, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
/**
* Removes niqqud from Hebrew string
*/
function hebrewStripNikkud(str) {
const a = str.normalize();
// now strip out niqqud and trope
return a.replace(/[\u0590-\u05bd]/g, '').replace(/[\u05bf-\u05c7]/g, '');
}
/*! @hebcal/hdate v0.22.0, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
/*
* More minimal HDate
*/
const NISAN = 1;
const IYYAR = 2;
const SIVAN = 3;
const TAMUZ = 4;
const AV = 5;
const ELUL = 6;
const TISHREI = 7;
const CHESHVAN = 8;
const KISLEV = 9;
const TEVET = 10;
const SHVAT = 11;
const ADAR_I = 12;
const ADAR_II = 13;
/**
* Hebrew months of the year (NISAN=1, TISHREI=7)
* @readonly
* @enum {number}
*/
const months = {
/** Av / אב */
AV,
/** Elul / אלול */
ELUL,
/** Tishrei / תִּשְׁרֵי */
TISHREI,
/** Adar Sheini (only on leap years) / אדר ב׳ */
ADAR_II,
};
const NISAN_STR = 'Nisan';
const monthNames0 = [
'',
NISAN_STR,
'Iyyar',
'Sivan',
'Tamuz',
'Av',
'Elul',
'Tishrei',
'Cheshvan',
'Kislev',
'Tevet',
"Sh'vat",
];
/*
* Transliterations of Hebrew month names.
* Regular years are index 0 and leap years are index 1.
* @private
*/
const monthNames = [
[...monthNames0, 'Adar', NISAN_STR],
[...monthNames0, 'Adar I', 'Adar II', NISAN_STR],
];
const edCache = new Map();
const EPOCH = -1373428;
// Avg year length in the cycle (19 solar years with 235 lunar months)
const AVG_HEBYEAR_DAYS = 365.24682220597794;
/**
* @private
*/
function assertNumber(n, name) {
if (typeof n !== 'number' || isNaN(n)) {
throw new TypeError(`param '${name}' not a number: ${n}`);
}
}
/**
* Converts Hebrew date to R.D. (Rata Die) fixed days.
* R.D. 1 is the imaginary date Monday, January 1, 1 on the Gregorian
* Calendar.
* @param year Hebrew year
* @param month Hebrew month
* @param day Hebrew date (1-30)
* @example
* const abs = hebrew2abs(5769, months.CHESHVAN, 15);
*/
function hebrew2abs(year, month, day) {
assertNumber(year, 'year');
assertNumber(month, 'month');
assertNumber(day, 'day');
if (year < 1) {
throw new RangeError(`hebrew2abs: invalid year ${year}`);
}
let tempabs = day;
if (month < TISHREI) {
for (let m = TISHREI; m <= monthsInYear(year); m++) {
tempabs += daysInMonth(m, year);
}
for (let m = NISAN; m < month; m++) {
tempabs += daysInMonth(m, year);
}
}
else {
for (let m = TISHREI; m < month; m++) {
tempabs += daysInMonth(m, year);
}
}
return EPOCH + elapsedDays(year) + tempabs - 1;
}
/**
* @private
*/
function newYear(year) {
return EPOCH + elapsedDays(year);
}
/**
* Converts absolute R.D. days to Hebrew date
* @param abs absolute R.D. days
*/
function abs2hebrew(abs) {
assertNumber(abs, 'abs');
abs = Math.trunc(abs);
if (abs <= EPOCH) {
throw new RangeError(`abs2hebrew: ${abs} is before epoch`);
}
// first, quickly approximate year
let year = Math.floor((abs - EPOCH) / AVG_HEBYEAR_DAYS);
while (newYear(year) <= abs) {
++year;
}
--year;
let month = abs < hebrew2abs(year, 1, 1) ? 7 : 1;
while (abs > hebrew2abs(year, month, daysInMonth(month, year))) {
++month;
}
const day = 1 + abs - hebrew2abs(year, month, 1);
return { yy: year, mm: month, dd: day };
}
/**
* Returns true if Hebrew year is a leap year
* @param year Hebrew year
*/
function isLeapYear(year) {
return (1 + year * 7) % 19 < 7;
}
/**
* Number of months in this Hebrew year (either 12 or 13 depending on leap year)
* @param year Hebrew year
*/
function monthsInYear(year) {
return 12 + +isLeapYear(year); // boolean is cast to 1 or 0
}
/**
* Number of days in Hebrew month in a given year (29 or 30)
* @param month Hebrew month (e.g. months.TISHREI)
* @param year Hebrew year
*/
function daysInMonth(month, year) {
switch (month) {
case IYYAR:
case TAMUZ:
case ELUL:
case TEVET:
case ADAR_II:
return 29;
}
if ((month === ADAR_I && !isLeapYear(year)) ||
(month === CHESHVAN && !longCheshvan(year)) ||
(month === KISLEV && shortKislev(year))) {
return 29;
}
else {
return 30;
}
}
/**
* Returns a transliterated string name of Hebrew month in year,
* for example 'Elul' or 'Cheshvan'.
* @param month Hebrew month (e.g. months.TISHREI)
* @param year Hebrew year
*/
function getMonthName(month, year) {
assertNumber(month, 'month');
assertNumber(year, 'year');
if (month < 1 || month > 14) {
throw new TypeError(`bad monthNum: ${month}`);
}
return monthNames[+isLeapYear(year)][month];
}
/**
* Days from sunday prior to start of Hebrew calendar to mean
* conjunction of Tishrei in Hebrew YEAR
* @param year Hebrew year
*/
function elapsedDays(year) {
const n = edCache.get(year);
if (typeof n === 'number') {
return n;
}
const elapsed = elapsedDays0(year);
edCache.set(year, elapsed);
return elapsed;
}
/**
* Days from sunday prior to start of Hebrew calendar to mean
* conjunction of Tishrei in Hebrew YEAR
* @private
* @param year Hebrew year
*/
function elapsedDays0(year) {
const prevYear = year - 1;
const mElapsed = 235 * Math.floor(prevYear / 19) + // Months in complete 19 year lunar (Metonic) cycles so far
12 * (prevYear % 19) + // Regular months in this cycle
Math.floor(((prevYear % 19) * 7 + 1) / 19); // Leap months this cycle
const pElapsed = 204 + 793 * (mElapsed % 1080);
const hElapsed = 5 +
12 * mElapsed +
793 * Math.floor(mElapsed / 1080) +
Math.floor(pElapsed / 1080);
const parts = (pElapsed % 1080) + 1080 * (hElapsed % 24);
const day = 1 + 29 * mElapsed + Math.floor(hElapsed / 24);
let altDay = day;
if (parts >= 19440 ||
(2 === day % 7 && parts >= 9924 && !isLeapYear(year)) ||
(1 === day % 7 && parts >= 16789 && isLeapYear(prevYear))) {
altDay++;
}
if (altDay % 7 === 0 || altDay % 7 === 3 || altDay % 7 === 5) {
return altDay + 1;
}
else {
return altDay;
}
}
/**
* Number of days in the hebrew YEAR.
* A common Hebrew calendar year can have a length of 353, 354 or 355 days
* A leap Hebrew calendar year can have a length of 383, 384 or 385 days
* @param year Hebrew year
*/
function daysInYear(year) {
return elapsedDays(year + 1) - elapsedDays(year);
}
/**
* true if Cheshvan is long in Hebrew year
* @param year Hebrew year
*/
function longCheshvan(year) {
return daysInYear(year) % 10 === 5;
}
/**
* true if Kislev is short in Hebrew year
* @param year Hebrew year
*/
function shortKislev(year) {
return daysInYear(year) % 10 === 3;
}
/**
* Converts Hebrew month string name to numeric
* @param monthName monthName
*/
function monthFromName(monthName) {
if (typeof monthName === 'number') {
if (isNaN(monthName) || monthName < 1 || monthName > 14) {
throw new RangeError(`bad monthName: ${monthName}`);
}
return monthName;
}
let c = monthName.trim().toLowerCase();
// remove all niqud and trailing gershayim (for Adar Alef/Bet)
c = hebrewStripNikkud(c).replace(/׳$/, '');
// If Hebrew month starts with a bet (for example `בתמוז`) then ignore it
if (c.startsWith('ב')) {
c = c.substring(1);
}
/*
the Hebrew months are unique to their second letter
N Nisan (November?)
I Iyyar
E Elul
C Cheshvan
K Kislev
1 1Adar
2 2Adar
Si Sh Sivan, Shvat
Ta Ti Te Tamuz, Tishrei, Tevet
Av Ad Av, Adar
אב אד אי אל אב אדר אייר אלול
ח חשון
ט טבת
כ כסלו
נ ניסן
ס סיון
ש שבט
תמ תש תמוז תשרי
*/
switch (c[0]) {
case 'n':
case 'נ':
if (c[1] === 'o') {
break; /* this catches "november" */
}
return NISAN;
case 'i':
return IYYAR;
case 'e':
return ELUL;
case 'c':
case 'ח':
return CHESHVAN;
case 'k':
case 'כ':
return KISLEV;
case 's':
switch (c[1]) {
case 'i':
return SIVAN;
case 'h':
return SHVAT;
}
break;
case 't':
switch (c[1]) {
case 'a':
return TAMUZ;
case 'i':
return TISHREI;
case 'e':
return TEVET;
}
break;
case 'a':
switch (c[1]) {
case 'v':
return AV;
case 'd':
if (/(1|[^i]i|a|א)$/i.test(c)) {
return ADAR_I;
}
return ADAR_II; // else assume sheini
}
break;
case 'ס':
return SIVAN;
case 'ט':
return TEVET;
case 'ש':
return SHVAT;
case 'א':
switch (c[1]) {
case 'ב':
return AV;
case 'ד':
if (/(1|[^i]i|a|א)$/i.test(c)) {
return ADAR_I;
}
return ADAR_II; // else assume sheini
case 'י':
return IYYAR;
case 'ל':
return ELUL;
}
break;
case 'ת':
switch (c[1]) {
case 'מ':
return TAMUZ;
case 'ש':
return TISHREI;
}
break;
}
throw new RangeError(`bad monthName: ${monthName}`);
}
/*! @hebcal/hdate v0.22.0, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
const GERESH = '׳';
const GERSHAYIM = '״';
const heb2num = {
א: 1,
ב: 2,
ג: 3,
ד: 4,
ה: 5,
ו: 6,
ז: 7,
ח: 8,
ט: 9,
י: 10,
כ: 20,
ל: 30,
מ: 40,
נ: 50,
ס: 60,
ע: 70,
פ: 80,
צ: 90,
ק: 100,
ר: 200,
ש: 300,
ת: 400,
};
const num2heb = {};
for (const [key, val] of Object.entries(heb2num)) {
num2heb[val] = key;
}
function num2digits(num) {
const digits = [];
while (num > 0) {
if (num === 15 || num === 16) {
digits.push(9);
digits.push(num - 9);
break;
}
let incr = 100;
let i;
for (i = 400; i > num; i -= incr) {
if (i === incr) {
incr = incr / 10;
}
}
digits.push(i);
num -= i;
}
return digits;
}
/**
* Converts a numerical value to a string of Hebrew letters.
*
* When specifying years of the Hebrew calendar in the present millennium,
* we omit the thousands (which is presently 5 [ה]).
* @example
* gematriya(5774) // 'תשע״ד' - cropped to 774
* gematriya(25) // 'כ״ה'
* gematriya(60) // 'ס׳'
* gematriya(3761) // 'ג׳תשס״א'
* gematriya(1123) // 'א׳קכ״ג'
*/
function gematriya(num) {
const num1 = parseInt(num, 10);
if (!num1 || num1 < 0) {
throw new TypeError(`invalid number: ${num}`);
}
let str = '';
const thousands = Math.floor(num1 / 1000);
if (thousands > 0 && thousands !== 5) {
const tdigits = num2digits(thousands);
for (const tdig of tdigits) {
str += num2heb[tdig];
}
str += GERESH;
}
const digits = num2digits(num1 % 1000);
if (digits.length === 1) {
return str + num2heb[digits[0]] + GERESH;
}
for (let i = 0; i < digits.length; i++) {
if (i + 1 === digits.length) {
str += GERSHAYIM;
}
str += num2heb[digits[i]];
}
return str;
}
/**
* Converts a string of Hebrew letters to a numerical value.
*
* Only considers the value of Hebrew letters `א` through `ת`.
* Ignores final Hebrew letters such as `ך` (kaf sofit) or `ם` (mem sofit)
* and vowels (nekudot).
*/
function gematriyaStrToNum(str) {
let num = 0;
const gereshIdx = str.indexOf(GERESH);
if (gereshIdx !== -1 && gereshIdx !== str.length - 1) {
const thousands = str.substring(0, gereshIdx);
num += gematriyaStrToNum(thousands) * 1000;
str = str.substring(gereshIdx);
}
for (const ch of str) {
const n = heb2num[ch];
if (typeof n === 'number') {
num += n;
}
}
return num;
}
/*! @hebcal/hdate v0.22.0, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
var poAshkenazi = { "headers": { "plural-forms": "nplurals=2; plural=(n > 1);", "language": "en_CA@ashkenazi" }, "contexts": { "": { "Tevet": ["Teves"] } } };
/*! @hebcal/hdate v0.22.0, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
var poHe = { "headers": { "plural-forms": "nplurals=2; plural=(n > 1);", "language": "he" }, "contexts": { "": { "Adar": ["אֲדָר"], "Adar I": ["אֲדָר א׳"], "Adar II": ["אֲדָר ב׳"], "Av": ["אָב"], "Cheshvan": ["חֶשְׁוָן"], "Elul": ["אֱלוּל"], "Iyyar": ["אִיָּיר"], "Kislev": ["כִּסְלֵו"], "Nisan": ["נִיסָן"], "Sh'vat": ["שְׁבָט"], "Sivan": ["סִיוָן"], "Tamuz": ["תַּמּוּז"], "Tammuz": ["תַּמּוּז"], "Tevet": ["טֵבֵת"], "Tishrei": ["תִּשְׁרֵי"] } } };
/*! @hebcal/hdate v0.22.0, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
const noopLocale = {
headers: { 'plural-forms': 'nplurals=2; plural=(n!=1);' },
contexts: { '': {} },
};
const alias = {
h: 'he',
a: 'ashkenazi',
s: 'en',
'': 'en',
};
/** @private */
const locales = new Map();
/** @private */
function getEnOrdinal(n) {
const s = ['th', 'st', 'nd', 'rd'];
const v = n % 100;
return n + (s[(v - 20) % 10] || s[v] || s[0]);
}
/** @private */
function checkLocale(locale) {
if (typeof locale !== 'string') {
throw new TypeError(`Invalid locale name: ${locale}`);
}
locale = alias[locale] || locale;
return locale.toLowerCase();
}
/** @private */
function getExistingLocale(locale) {
const locale1 = checkLocale(locale);
const loc = locales.get(locale1);
if (!loc) {
throw new RangeError(`Locale '${locale}' not found`);
}
return loc;
}
/**
* A locale in Hebcal is used for translations/transliterations of
* holidays. `@hebcal/hdate` supports four locales by default
* * `en` - default, Sephardic transliterations (e.g. "Shabbat")
* * `ashkenazi` - Ashkenazi transliterations (e.g. "Shabbos")
* * `he` - Hebrew (e.g. "שַׁבָּת")
* * `he-x-NoNikud` - Hebrew without nikud (e.g. "שבת")
*/
class Locale {
/**
* Returns translation only if `locale` offers a non-empty translation for `id`.
* Otherwise, returns `undefined`.
* @param id Message ID to translate
* @param [locale] Optional locale name (i.e: `'he'`, `'fr'`). Defaults to no-op locale.
*/
static lookupTranslation(id, locale) {
const loc = (typeof locale === 'string' && locales.get(checkLocale(locale))) ||
noopLocale.contexts[''];
const array = loc[id];
if (array?.length && array[0].length) {
return array[0];
}
return undefined;
}
/**
* By default, if no translation was found, returns `id`.
* @param id Message ID to translate
* @param [locale] Optional locale name (i.e: `'he'`, `'fr'`). Defaults to no-op locale.
*/
static gettext(id, locale) {
const text = this.lookupTranslation(id, locale);
if (text === undefined) {
return id;
}
return text;
}
/**
* Register locale translations.
* @param locale Locale name (i.e.: `'he'`, `'fr'`)
* @param data parsed data from a `.po` file.
*/
static addLocale(locale, data) {
locale = checkLocale(locale);
const ctx = data.contexts;
if (typeof ctx !== 'object' || typeof ctx[''] !== 'object') {
throw new TypeError(`Locale '${locale}' invalid compact format`);
}
locales.set(locale, ctx['']);
}
/**
* Adds a translation to `locale`, replacing any previous translation.
* @param locale Locale name (i.e: `'he'`, `'fr'`).
* @param id Message ID to translate
* @param translation Translation text
*/
static addTranslation(locale, id, translation) {
const loc = getExistingLocale(locale);
if (typeof id !== 'string' || id.length === 0) {
throw new TypeError(`Invalid id string: ${id}`);
}
const isArray = Array.isArray(translation);
if (isArray) {
const t0 = translation[0];
if (typeof t0 !== 'string' || t0.length === 0) {
throw new TypeError(`Invalid translation array: ${translation}`);
}
}
else if (typeof translation !== 'string') {
throw new TypeError(`Invalid translation string: ${translation}`);
}
loc[id] = isArray ? translation : [translation];
}
/**
* Adds multiple translations to `locale`, replacing any previous translations.
* @param locale Locale name (i.e: `'he'`, `'fr'`).
* @param data parsed data from a `.po` file.
*/
static addTranslations(locale, data) {
const loc = getExistingLocale(locale);
const ctx = data.contexts;
if (typeof ctx !== 'object' || typeof ctx[''] !== 'object') {
throw new TypeError(`Locale '${locale}' invalid compact format`);
}
Object.assign(loc, ctx['']);
}
/**
* Returns the names of registered locales
*/
static getLocaleNames() {
const keys = Array.from(locales.keys());
return keys.sort((a, b) => a.localeCompare(b));
}
/**
* Checks whether a locale has been registered
* @param locale Locale name (i.e: `'he'`, `'fr'`).
*/
static hasLocale(locale) {
const locale1 = checkLocale(locale);
return locales.has(locale1);
}
/**
* Renders a number in ordinal, such as 1st, 2nd or 3rd
* @param [locale] Optional locale name (i.e: `'he'`, `'fr'`). Defaults to no-op locale.
*/
static ordinal(n, locale) {
let locale0 = locale?.toLowerCase();
if (!locale0) {
return getEnOrdinal(n);
}
locale0 = alias[locale0] || locale0;
switch (locale0) {
case 'en':
case 'ashkenazi':
return getEnOrdinal(n);
case 'es':
return n + 'º';
case 'he':
case 'he-x-nonikud':
return String(n);
}
if (locale0.startsWith('ashkenazi')) {
return getEnOrdinal(n);
}
return n + '.';
}
/**
* Removes nekudot from Hebrew string
*/
static hebrewStripNikkud(str) {
return hebrewStripNikkud(str);
}
/**
* Makes a copy of entire Hebrew locale with no niqqud
*/
static copyLocaleNoNikud(data) {
const strs = data.contexts[''];
const m = {};
for (const [key, val] of Object.entries(strs)) {
m[key] = [hebrewStripNikkud(val[0])];
}
return {
headers: data.headers,
contexts: { '': m },
};
}
}
Locale.addLocale('en', noopLocale);
/* Ashkenazic transliterations */
Locale.addLocale('ashkenazi', poAshkenazi);
/* Hebrew with nikkud */
Locale.addLocale('he', poHe);
/* Hebrew without nikkud */
const poHeNoNikud = Locale.copyLocaleNoNikud(poHe);
Locale.addLocale('he-x-NoNikud', poHeNoNikud);
/*! @hebcal/hdate v0.22.0, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
/*
Hebcal - A Jewish Calendar Generator
Copyright (c) 1994-2020 Danny Sadinoff
Portions copyright Eyal Schachter and Michael J. Radwin
https://github.com/hebcal/hebcal-es6
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
function mod(x, y) {
return x - y * Math.floor(x / y);
}
function isSimpleHebrewDate(obj) {
return obj.yy !== undefined;
}
const UNITS_DAY = 'day';
const UNITS_WEEK = 'week';
const UNITS_MONTH = 'month';
const UNITS_YEAR = 'year';
/**
* A `HDate` represents a Hebrew calendar date.
*
* An instance of this class encapsulates a date in the Hebrew calendar system.
* It consists of a year, month, and day, without any associated time or location data.
* The Hebrew calendar is a lunisolar calendar, meaning it is based on both lunar and solar cycles.
*
* A Hebrew date internally stores three numbers:
* - year: The Hebrew year (1-9999). Counted from the traditional Hebrew date of creation (3761 BCE in the Gregorian calendar)
* - month: The Hebrew month (1-13). Month 1 is Nisan, month 7 is Tishrei. There are 12 months in a regular year and 13 months in a leap year.
* - day: The day of the month (1-30)
*
* This class uses Rata Die to convert between the Hebrew and Gregorian calendars.
*
* To calculate times of day, use `Zmanim` class from `@hebcal/core`
* @see {@link https://en.wikipedia.org/wiki/Rata_Die | Rata Die}
* @see {@link https://hebcal.github.io/api/core/classes/Zmanim.html | Zmanim}
*/
class HDate {
/** Hebrew year, 1-9999 */
yy;
/** Hebrew month of year (1=NISAN, 7=TISHREI) */
mm;
/** Hebrew day within the month (1-30) */
dd;
/** absolute Rata Die (R.D.) days */
rd;
/**
* Create a Hebrew date. There are 3 basic forms for the `HDate()` constructor.
*
* 1. No parameters - represents the current Hebrew date at time of instantiation
* 2. One parameter
* * `Date` - represents the Hebrew date corresponding to the Gregorian date using
* local time. Hours, minutes, seconds and milliseconds are ignored.
* * `HDate` - clones a copy of the given Hebrew date
* * `number` - Converts absolute R.D. days to Hebrew date.
* R.D. 1 == the imaginary date January 1, 1 (Gregorian)
* 3. Three parameters: Hebrew day, Hebrew month, Hebrew year. Hebrew day should
* be a number between 1-30, Hebrew month can be a number or string, and
* Hebrew year is always a number.
* @example
* import {HDate, months} from '@hebcal/hdate';
*
* const hd1 = new HDate();
* const hd2 = new HDate(new Date(2008, 10, 13));
* const hd3 = new HDate(15, 'Cheshvan', 5769);
* const hd4 = new HDate(15, months.CHESHVAN, 5769);
* const hd5 = new HDate(733359); // ==> 15 Cheshvan 5769
* const monthName = 'אייר';
* const hd6 = new HDate(5, monthName, 5773);
* @param [day] - Day of month (1-30) if a `number`.
* If a `Date` is specified, represents the Hebrew date corresponding to the
* Gregorian date using local time.
* If an `HDate` is specified, clones a copy of the given Hebrew date.
* @param [month] - Hebrew month of year (1=NISAN, 7=TISHREI)
* @param [year] - Hebrew year
*/
constructor(day, month, year) {
if (arguments.length === 2 || arguments.length > 3) {
throw new TypeError('HDate constructor requires 0, 1 or 3 arguments');
}
if (arguments.length === 3) {
// Hebrew day, Hebrew month, Hebrew year
this.dd = this.mm = 1;
const yy = typeof year === 'string' ? parseInt(year, 10) : year;
if (isNaN(yy)) {
throw new TypeError(`HDate called with bad year: ${year}`);
}
this.yy = yy;
setMonth(this, month); // will throw if we can't parse
const dd = typeof day === 'string' ? parseInt(day, 10) : day;
if (isNaN(dd)) {
throw new TypeError(`HDate called with bad day: ${day}`);
}
setDate(this, dd);
}
else {
// 0 arguments
if (day === undefined || day === null) {
day = new Date();
}
// 1 argument
const abs0 = typeof day === 'number' && !isNaN(day)
? day
: isDate(day)
? greg2abs(day)
: isSimpleHebrewDate(day)
? day
: null;
if (abs0 === null) {
throw new TypeError(`HDate called with bad arg: ${day}`);
}
const isNumber = typeof abs0 === 'number';
const d = isNumber ? abs2hebrew(abs0) : abs0;
this.yy = d.yy;
this.mm = d.mm;
this.dd = d.dd;
if (isNumber) {
this.rd = abs0;
}
}
}
/**
* Returns the Hebrew year of this Hebrew date
* @returns an integer >= 1
* @example
* const hd = new HDate(new Date(2008, 10, 13)); // 15 Cheshvan 5769
* hd.getFullYear(); // 5769
*/
getFullYear() {
return this.yy;
}
/**
* Returns `true` if this Hebrew date occurs during a Hebrew leap year
* @example
* const hd = new HDate(new Date(2008, 10, 13)); // 15 Cheshvan 5769
* hd.isLeapYear(); // false
*/
isLeapYear() {
return isLeapYear(this.yy);
}
/**
* Returns the Hebrew month (1=NISAN, 7=TISHREI) of this Hebrew date
* @returns an integer 1-13
* @example
* const hd = new HDate(new Date(2008, 10, 13)); // 15 Cheshvan 5769
* hd.getMonth(); // 8
*/
getMonth() {
return this.mm;
}
/**
* The Tishrei-based month of this Hebrew date. 1 is Tishrei, 7 is Nisan, 13 is Elul in a leap year
* @returns an integer 1-13
* @example
* const hd = new HDate(new Date(2008, 10, 13)); // 15 Cheshvan 5769
* hd.getTishreiMonth(); // 2
*/
getTishreiMonth() {
const nummonths = monthsInYear(this.getFullYear());
return (this.getMonth() + nummonths - 6) % nummonths || nummonths;
}
/**
* Number of days in the month of this Hebrew date (29 or 30)
* @returns an integer 29-30
* @example
* const hd = new HDate(new Date(2008, 10, 13)); // 15 Cheshvan 5769
* hd.daysInMonth(); // 29
*/
daysInMonth() {
return daysInMonth(this.getMonth(), this.getFullYear());
}
/**
* Gets the day within the month (1-30)
* @returns an integer 1-30
* @example
* const hd = new HDate(new Date(2008, 10, 13)); // 15 Cheshvan 5769
* hd.getDate(); // 15
*/
getDate() {
return this.dd;
}
/**
* Returns the day of the week for this Hebrew date,
* where 0 represents Sunday, 1 represents Monday, 6 represents Saturday.
*
* For the day of the month, see `getDate()`
* @returns an integer 0-6
* @example
* const hd = new HDate(new Date(2008, 10, 13)); // 15 Cheshvan 5769
* hd.getDate(); // 4
*/
getDay() {
return mod(this.abs(), 7);
}
/**
* Converts this Hebrew date to the corresponding Gregorian date.
*
* The returned `Date` object will be in the local (i.e. host system) time zone.
* Hours, minutes, seconds and milliseconds will all be zero.
*
* Note that this function returns the daytime portion of the date.
* For example, the 15th of Cheshvan 5769 began at sundown on
* 12 November 2008 and continues through 13 November 2008. This
* function would return only the date 13 November 2008.
* @example
* const hd = new HDate(15, 'Cheshvan', 5769);
* const date = hd.greg(); // 13 November 2008
* const year = date.getFullYear(); // 2008
* const monthNum = date.getMonth() + 1; // 11
* const day = date.getDate(); // 13
*/
greg() {
return abs2greg(this.abs());
}
/**
* Converts from Hebrew date representation to R.D. (Rata Die) fixed days.
* R.D. 1 is the imaginary date Monday, January 1, 1 (Gregorian).
* Note also that R.D. = Julian Date − 1,721,424.5
* @see {@link https://en.wikipedia.org/wiki/Rata_Die | Rata Die}
* @example
* const hd = new HDate(15, 'Cheshvan', 5769);
* hd.abs(); // 733359
*/
abs() {
if (typeof this.rd !== 'number') {
this.rd = hebrew2abs(this.yy, this.mm, this.dd);
}
return this.rd;
}
/**
* Converts Hebrew date to R.D. (Rata Die) fixed days.
* R.D. 1 is the imaginary date Monday, January 1, 1 on the Gregorian
* Calendar.
* @param year Hebrew year
* @param month Hebrew month (1=NISAN, 7=TISHREI)
* @param day Hebrew date (1-30)
* @example
* import {HDate, months} from '@hebcal/hdate';
* HDate.hebrew2abs(5769, months.CHESHVAN, 15); // 733359
*/
static hebrew2abs(year, month, day) {
return hebrew2abs(year, month, day);
}
/**
* Returns a transliterated Hebrew month name, e.g. `'Elul'` or `'Cheshvan'`.
* @example
* const hd = new HDate(new Date(2008, 10, 13)); // 15 Cheshvan 5769
* hd.getMonthName(); // 'Cheshvan'
*/
getMonthName() {
return getMonthName(this.getMonth(), this.getFullYear());
}
/**
* Renders this Hebrew date as a translated or transliterated string,
* including ordinal e.g. `'15th of Cheshvan, 5769'`.
* @example
* import {HDate, months} from '@hebcal/hdate';
*
* const hd = new HDate(15, months.CHESHVAN, 5769);
* console.log(hd.render('en')); // '15th of Cheshvan, 5769'
* console.log(hd.render('he')); // '15 חֶשְׁוָן, 5769'
* console.log(hd.render('en', false)); // '15th of Cheshvan'
* console.log(hd.render('he', false)); // '15 חֶשְׁוָן'
* @param [locale] Optional locale name (defaults to active locale).
* @param [showYear=true] Display year (defaults to true).
* @see {@link Locale}
*/
render(locale, showYear = true) {
const locale0 = locale || 'en';
const day = this.getDate();
const monthName0 = Locale.gettext(this.getMonthName(), locale0);
const monthName = monthName0.replace(/'/g, '’');
const nth = Locale.ordinal(day, locale0);
const dayOf = getDayOfTranslation(locale0);
const dateStr = `${nth}${dayOf} ${monthName}`;
if (showYear) {
const fullYear = this.getFullYear();
return `${dateStr}, ${fullYear}`;
}
else {
return dateStr;
}
}
/**
* Renders this Hebrew date in Hebrew gematriya, regardless of locale.
* @param suppressNikud - suppress nekudot (default false)
* @param suppressYear - suppress Hebrew year (default false)
* @example
* import {HDate, months} from '@hebcal/hdate';
* const hd = new HDate(15, months.CHESHVAN, 5769);
* hd.renderGematriya(); // 'ט״ו חֶשְׁוָן תשס״ט'
* hd.renderGematriya(true); // 'ט״ו חשון תשס״ט'
* hd.renderGematriya(false, true); // 'ט״ו חֶשְׁוָן'
*/
renderGematriya(suppressNikud = false, suppressYear = false) {
const d = this.getDate();
const locale = suppressNikud ? 'he-x-NoNikud' : 'he';
const m = Locale.gettext(this.getMonthName(), locale);
const prefix = gematriya(d) + ' ' + m;
if (suppressYear) {
return prefix;
}
const y = this.getFullYear();
return prefix + ' ' + gematriya(y);
}
/**
* Returns an `HDate` corresponding to the specified day of week
* **before** this Hebrew date
* @example
* new HDate(new Date('Wednesday February 19, 2014')).before(6).greg() // Sat Feb 15 2014
* @param dayOfWeek day of week: Sunday=0, Saturday=6
*/
before(dayOfWeek) {
return onOrBefore(dayOfWeek, this, -1);
}
/**
* Returns an `HDate` corresponding to the specified day of week
* **on or before** this Hebrew date
* @example
* new HDate(new Date('Wednesday February 19, 2014')).onOrBefore(6).greg() // Sat Feb 15 2014
* new HDate(new Date('Saturday February 22, 2014')).onOrBefore(6).greg() // Sat Feb 22 2014
* new HDate(new Date('Sunday February 23, 2014')).onOrBefore(6).greg() // Sat Feb 22 2014
* @param dayOfWeek day of week: Sunday=0, Saturday=6
*/
onOrBefore(dayOfWeek) {
return onOrBefore(dayOfWeek, this, 0);
}
/**
* Returns an `HDate` corresponding to the specified day of week
* **nearest** to this Hebrew date
* @example
* new HDate(new Date('Wednesday February 19, 2014')).nearest(6).greg() // Sat Feb 22 2014
* new HDate(new Date('Tuesday February 18, 2014')).nearest(6).greg() // Sat Feb 15 2014
* @param dayOfWeek day of week: Sunday=0, Saturday=6
*/
nearest(dayOfWeek) {
return onOrBefore(dayOfWeek, this, 3);
}
/**
* Returns an `HDate` corresponding to the specified day of week
* **on or after** this Hebrew date
* @example
* new HDate(new Date('Wednesday February 19, 2014')).onOrAfter(6).greg() // Sat Feb 22 2014
* new HDate(new Date('Saturday February 22, 2014')).onOrAfter(6).greg() // Sat Feb 22 2014
* new HDate(new Date('Sunday February 23, 2014')).onOrAfter(6).greg() // Sat Mar 01 2014
* @param dayOfWeek day of week: Sunday=0, Saturday=6
*/
onOrAfter(dayOfWeek) {
return onOrBefore(dayOfWeek, this, 6);
}
/**
* Returns an `HDate` corresponding to the specified day of week
* **after** this Hebrew date
* @example
* new HDate(new Date('Wednesday February 19, 2014')).after(6).greg() // Sat Feb 22 2014
* new HDate(new Date('Saturday February 22, 2014')).after(6).greg() // Sat Mar 01 2014
* new HDate(new Date('Sunday February 23, 2014')).after(6).greg() // Sat Mar 01 2014
* @param dayOfWeek day of week: Sunday=0, Saturday=6
*/
after(dayOfWeek) {
return onOrBefore(dayOfWeek, this, 7);
}
/**
* Returns the next Hebrew date
* @example
* const hd = new HDate(new Date(2008, 10, 13)); // 15 Cheshvan 5769
* hd.next(); // '16 Cheshvan 5769'
*/
next() {
return new HDate(this.abs() + 1);
}
/**
* Returns the previous Hebrew date
* @example
* const hd = new HDate(new Date(2008, 10, 13)); // 15 Cheshvan 5769
* hd.prev(); // '14 Cheshvan 5769'
*/
prev() {
return new HDate(this.abs() - 1);
}
/**
* Returns a cloned `HDate` object with a specified amount of time added
*
* Units are case insensitive, and support plural and short forms.
* Note, short forms are case sensitive.
*
* | Unit | Shorthand | Description
* | --- | --- | --- |
* | `day` | `d` | days |
* | `week` | `w` | weeks |
* | `month` | `M` | months |
* | `year` | `y` | years |
*/
add(amount, units = 'd') {
amount = typeof amount === 'string' ? parseInt(amount, 10) : amount;
if (!amount) {
return new HDate(this);
}
units = standardizeUnits(units);
if (units === UNITS_DAY) {
return new HDate(this.abs() + amount);
}
else if (units === UNITS_WEEK) {
return new HDate(this.abs() + 7 * amount);
}
else if (units === UNITS_YEAR) {
return new HDate(this.getDate(), this.getMonth(), this.getFullYear() + amount);
}
else {
// units === UNITS_MONTH
let hd = new HDate(this);
const sign = amount > 0 ? 1 : -1;
amount = Math.abs(amount);
for (let i = 0; i < amount; i++) {
hd = new HDate(hd.abs() + sign * hd.daysInMonth());
}
return hd;
}
}
/**
* Returns a cloned `HDate` object with a specified amount of time subracted
*
* Units are case insensitive, and support plural and short forms.
* Note, short forms are case sensitive.
*
* | Unit | Shorthand | Description
* | --- | --- | --- |
* | `day` | `d` | days |
* | `week` | `w` | weeks |
* | `month` | `M` | months |
* | `year` | `y` | years |
* @example
* import {HDate, months} from '@hebcal/hdate';
*
* const hd1 = new HDate(15, months.CHESHVAN, 57