@hebcal/core 5.9.6 → 5.9.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundle.js +21 -16
- package/dist/bundle.js.map +1 -1
- package/dist/bundle.min.js +16 -16
- package/dist/bundle.min.js.map +1 -1
- package/dist/esm/DailyLearning.js +1 -1
- package/dist/esm/HebrewDateEvent.js +1 -1
- package/dist/esm/HolidayEvent.js +1 -1
- package/dist/esm/MevarchimChodeshEvent.js +1 -1
- package/dist/esm/ParshaEvent.js +1 -1
- package/dist/esm/TimedEvent.js +1 -1
- package/dist/esm/YomKippurKatanEvent.js +1 -1
- package/dist/esm/ashkenazi.po.js +1 -1
- package/dist/esm/calendar.js +1 -1
- package/dist/esm/candles.js +1 -1
- package/dist/esm/event.js +1 -1
- package/dist/esm/getStartAndEnd.js +1 -1
- package/dist/esm/hallel.js +1 -1
- package/dist/esm/he-x-NoNikud.po.d.ts +12 -0
- package/dist/esm/he-x-NoNikud.po.js +5 -0
- package/dist/esm/he-x-NoNikud.po.js.map +1 -0
- package/dist/esm/he.po.js +2 -2
- package/dist/esm/he.po.js.map +1 -1
- package/dist/esm/hebcal.js +1 -1
- package/dist/esm/holidays.js +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/locale.js +3 -1
- package/dist/esm/locale.js.map +1 -1
- package/dist/esm/location.js +1 -1
- package/dist/esm/modern.js +1 -1
- package/dist/esm/molad.js +1 -1
- package/dist/esm/omer.js +1 -1
- package/dist/esm/parshaName.js +1 -1
- package/dist/esm/parshaYear.js +1 -1
- package/dist/esm/pkgVersion.d.ts +1 -1
- package/dist/esm/pkgVersion.js +2 -2
- package/dist/esm/pkgVersion.js.map +1 -1
- package/dist/esm/reformatTimeStr.js +1 -1
- package/dist/esm/sedra.js +1 -1
- package/dist/esm/staticHolidays.js +1 -1
- package/dist/esm/tachanun.js +1 -1
- package/dist/esm/zmanim.js +1 -1
- package/dist/he-x-NoNikud.po.d.ts +12 -0
- package/dist/index.cjs +3184 -242
- package/dist/index.cjs.map +1 -1
- package/dist/pkgVersion.d.ts +1 -1
- package/package.json +6 -6
package/dist/index.cjs
CHANGED
|
@@ -1,32 +1,1899 @@
|
|
|
1
|
-
/*! @hebcal/core v5.9.
|
|
1
|
+
/*! @hebcal/core v5.9.8, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var hdate = require('@hebcal/hdate');
|
|
5
|
-
var noaa = require('@hebcal/noaa');
|
|
6
4
|
require('temporal-polyfill/global');
|
|
7
5
|
|
|
8
6
|
/** DO NOT EDIT THIS AUTO-GENERATED FILE! */
|
|
9
|
-
const version = '5.9.
|
|
7
|
+
const version = '5.9.8';
|
|
8
|
+
|
|
9
|
+
/*! @hebcal/hdate v0.14.2, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
|
|
10
|
+
/* eslint-disable @typescript-eslint/no-namespace, no-inner-declarations */
|
|
11
|
+
/** @private */
|
|
12
|
+
const lengths = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
13
|
+
/** @private */
|
|
14
|
+
const monthLengths = [lengths, lengths.slice()];
|
|
15
|
+
monthLengths[1][2] = 29;
|
|
16
|
+
/**
|
|
17
|
+
* @private
|
|
18
|
+
*/
|
|
19
|
+
function mod$1(x, y) {
|
|
20
|
+
return x - y * Math.floor(x / y);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* @private
|
|
24
|
+
*/
|
|
25
|
+
function quotient(x, y) {
|
|
26
|
+
return Math.floor(x / y);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* @private
|
|
30
|
+
* @param abs - R.D. number of days
|
|
31
|
+
*/
|
|
32
|
+
function yearFromFixed(abs) {
|
|
33
|
+
const l0 = abs - 1;
|
|
34
|
+
const n400 = quotient(l0, 146097);
|
|
35
|
+
const d1 = mod$1(l0, 146097);
|
|
36
|
+
const n100 = quotient(d1, 36524);
|
|
37
|
+
const d2 = mod$1(d1, 36524);
|
|
38
|
+
const n4 = quotient(d2, 1461);
|
|
39
|
+
const d3 = mod$1(d2, 1461);
|
|
40
|
+
const n1 = quotient(d3, 365);
|
|
41
|
+
const year = 400 * n400 + 100 * n100 + 4 * n4 + n1;
|
|
42
|
+
return n100 !== 4 && n1 !== 4 ? year + 1 : year;
|
|
43
|
+
}
|
|
44
|
+
/*
|
|
45
|
+
const ABS_14SEP1752 = 639797;
|
|
46
|
+
const ABS_2SEP1752 = 639785;
|
|
47
|
+
*/
|
|
48
|
+
/*
|
|
49
|
+
* Formerly in namespace, now top-level
|
|
50
|
+
*/
|
|
51
|
+
/**
|
|
52
|
+
* Returns true if the Gregorian year is a leap year
|
|
53
|
+
* @param year Gregorian year
|
|
54
|
+
*/
|
|
55
|
+
function isGregLeapYear(year) {
|
|
56
|
+
return !(year % 4) && (!!(year % 100) || !(year % 400));
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Number of days in the Gregorian month for given year
|
|
60
|
+
* @param month Gregorian month (1=January, 12=December)
|
|
61
|
+
* @param year Gregorian year
|
|
62
|
+
*/
|
|
63
|
+
function daysInGregMonth(month, year) {
|
|
64
|
+
// 1 based months
|
|
65
|
+
return monthLengths[+isGregLeapYear(year)][month];
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Returns true if the object is a Javascript Date
|
|
69
|
+
*/
|
|
70
|
+
function isDate(obj) {
|
|
71
|
+
// eslint-disable-next-line no-prototype-builtins
|
|
72
|
+
return typeof obj === 'object' && Date.prototype.isPrototypeOf(obj);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* @private
|
|
76
|
+
* @param year
|
|
77
|
+
* @param month (1-12)
|
|
78
|
+
* @param day (1-31)
|
|
79
|
+
*/
|
|
80
|
+
function toFixed(year, month, day) {
|
|
81
|
+
const py = year - 1;
|
|
82
|
+
return (365 * py +
|
|
83
|
+
quotient(py, 4) -
|
|
84
|
+
quotient(py, 100) +
|
|
85
|
+
quotient(py, 400) +
|
|
86
|
+
quotient(367 * month - 362, 12) +
|
|
87
|
+
(month <= 2 ? 0 : isGregLeapYear(year) ? -1 : -2) +
|
|
88
|
+
day);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Converts Gregorian date to absolute R.D. (Rata Die) days
|
|
92
|
+
* @param date Gregorian date
|
|
93
|
+
*/
|
|
94
|
+
function greg2abs(date) {
|
|
95
|
+
if (!isDate(date)) {
|
|
96
|
+
throw new TypeError(`not a Date: ${date}`);
|
|
97
|
+
}
|
|
98
|
+
else if (isNaN(date.getTime())) {
|
|
99
|
+
throw new RangeError('Invalid Date');
|
|
100
|
+
}
|
|
101
|
+
const abs = toFixed(date.getFullYear(), date.getMonth() + 1, date.getDate());
|
|
102
|
+
/*
|
|
103
|
+
if (abs < ABS_14SEP1752 && abs > ABS_2SEP1752) {
|
|
104
|
+
throw new RangeError(`Invalid Date: ${date}`);
|
|
105
|
+
}
|
|
106
|
+
*/
|
|
107
|
+
return abs;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Converts from Rata Die (R.D. number) to Gregorian date.
|
|
111
|
+
* See the footnote on page 384 of ``Calendrical Calculations, Part II:
|
|
112
|
+
* Three Historical Calendars'' by E. M. Reingold, N. Dershowitz, and S. M.
|
|
113
|
+
* Clamen, Software--Practice and Experience, Volume 23, Number 4
|
|
114
|
+
* (April, 1993), pages 383-404 for an explanation.
|
|
115
|
+
*
|
|
116
|
+
* Note that this function returns the daytime portion of the date.
|
|
117
|
+
* For example, the 15th of Cheshvan 5769 began at sundown on
|
|
118
|
+
* 12 November 2008 and continues through 13 November 2008. This
|
|
119
|
+
* function would return only the date 13 November 2008.
|
|
120
|
+
* @param abs - R.D. number of days
|
|
121
|
+
* @example
|
|
122
|
+
* const abs = hebrew2abs(5769, months.CHESHVAN, 15);
|
|
123
|
+
* const date = abs2greg(abs); // 13 November 2008
|
|
124
|
+
* const year = date.getFullYear(); // 2008
|
|
125
|
+
* const monthNum = date.getMonth() + 1; // 11
|
|
126
|
+
* const day = date.getDate(); // 13
|
|
127
|
+
*/
|
|
128
|
+
function abs2greg(abs) {
|
|
129
|
+
if (typeof abs !== 'number' || isNaN(abs)) {
|
|
130
|
+
throw new TypeError(`not a Number: ${abs}`);
|
|
131
|
+
}
|
|
132
|
+
abs = Math.trunc(abs);
|
|
133
|
+
/*
|
|
134
|
+
if (abs < ABS_14SEP1752 && abs > ABS_2SEP1752) {
|
|
135
|
+
throw new RangeError(`Invalid Date: ${abs}`);
|
|
136
|
+
}
|
|
137
|
+
*/
|
|
138
|
+
const year = yearFromFixed(abs);
|
|
139
|
+
const priorDays = abs - toFixed(year, 1, 1);
|
|
140
|
+
const correction = abs < toFixed(year, 3, 1) ? 0 : isGregLeapYear(year) ? 1 : 2;
|
|
141
|
+
const month = quotient(12 * (priorDays + correction) + 373, 367);
|
|
142
|
+
const day = abs - toFixed(year, month, 1) + 1;
|
|
143
|
+
const dt = new Date(year, month - 1, day);
|
|
144
|
+
if (year < 100 && year >= 0) {
|
|
145
|
+
dt.setFullYear(year);
|
|
146
|
+
}
|
|
147
|
+
return dt;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/*! @hebcal/hdate v0.14.2, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
|
|
151
|
+
|
|
152
|
+
/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-namespace */
|
|
153
|
+
/**
|
|
154
|
+
* Gregorian date helper functions
|
|
155
|
+
*/
|
|
156
|
+
exports.greg = void 0;
|
|
157
|
+
(function (greg) {
|
|
158
|
+
})(exports.greg || (exports.greg = {}));
|
|
159
|
+
exports.greg.abs2greg = abs2greg;
|
|
160
|
+
exports.greg.daysInMonth = daysInGregMonth;
|
|
161
|
+
exports.greg.greg2abs = greg2abs;
|
|
162
|
+
exports.greg.isDate = isDate;
|
|
163
|
+
exports.greg.isLeapYear = isGregLeapYear;
|
|
164
|
+
|
|
165
|
+
/*! @hebcal/hdate v0.14.2, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
|
|
166
|
+
/*
|
|
167
|
+
* More minimal HDate
|
|
168
|
+
*/
|
|
169
|
+
const NISAN$4 = 1;
|
|
170
|
+
const IYYAR$1 = 2;
|
|
171
|
+
const SIVAN$1 = 3;
|
|
172
|
+
const TAMUZ$1 = 4;
|
|
173
|
+
const AV$1 = 5;
|
|
174
|
+
const ELUL$1 = 6;
|
|
175
|
+
const TISHREI$2 = 7;
|
|
176
|
+
const CHESHVAN$1 = 8;
|
|
177
|
+
const KISLEV$2 = 9;
|
|
178
|
+
const TEVET$2 = 10;
|
|
179
|
+
const SHVAT$1 = 11;
|
|
180
|
+
const ADAR_I$2 = 12;
|
|
181
|
+
const ADAR_II$2 = 13;
|
|
182
|
+
/**
|
|
183
|
+
* Hebrew months of the year (NISAN=1, TISHREI=7)
|
|
184
|
+
* @readonly
|
|
185
|
+
* @enum {number}
|
|
186
|
+
*/
|
|
187
|
+
const months = {
|
|
188
|
+
/** Nissan / ניסן */
|
|
189
|
+
NISAN: NISAN$4,
|
|
190
|
+
/** Iyyar / אייר */
|
|
191
|
+
IYYAR: IYYAR$1,
|
|
192
|
+
/** Sivan / סיון */
|
|
193
|
+
SIVAN: SIVAN$1,
|
|
194
|
+
/** Tamuz (sometimes Tammuz) / תמוז */
|
|
195
|
+
TAMUZ: TAMUZ$1,
|
|
196
|
+
/** Av / אב */
|
|
197
|
+
AV: AV$1,
|
|
198
|
+
/** Elul / אלול */
|
|
199
|
+
ELUL: ELUL$1,
|
|
200
|
+
/** Tishrei / תִּשְׁרֵי */
|
|
201
|
+
TISHREI: TISHREI$2,
|
|
202
|
+
/** Cheshvan / חשון */
|
|
203
|
+
CHESHVAN: CHESHVAN$1,
|
|
204
|
+
/** Kislev / כסלו */
|
|
205
|
+
KISLEV: KISLEV$2,
|
|
206
|
+
/** Tevet / טבת */
|
|
207
|
+
TEVET: TEVET$2,
|
|
208
|
+
/** Sh'vat / שבט */
|
|
209
|
+
SHVAT: SHVAT$1,
|
|
210
|
+
/** Adar or Adar Rishon / אדר */
|
|
211
|
+
ADAR_I: ADAR_I$2,
|
|
212
|
+
/** Adar Sheini (only on leap years) / אדר ב׳ */
|
|
213
|
+
ADAR_II: ADAR_II$2,
|
|
214
|
+
};
|
|
215
|
+
const NISAN_STR = 'Nisan';
|
|
216
|
+
const monthNames0 = [
|
|
217
|
+
'',
|
|
218
|
+
NISAN_STR,
|
|
219
|
+
'Iyyar',
|
|
220
|
+
'Sivan',
|
|
221
|
+
'Tamuz',
|
|
222
|
+
'Av',
|
|
223
|
+
'Elul',
|
|
224
|
+
'Tishrei',
|
|
225
|
+
'Cheshvan',
|
|
226
|
+
'Kislev',
|
|
227
|
+
'Tevet',
|
|
228
|
+
"Sh'vat",
|
|
229
|
+
];
|
|
230
|
+
/*
|
|
231
|
+
* Transliterations of Hebrew month names.
|
|
232
|
+
* Regular years are index 0 and leap years are index 1.
|
|
233
|
+
* @private
|
|
234
|
+
*/
|
|
235
|
+
const monthNames = [
|
|
236
|
+
[...monthNames0, 'Adar', NISAN_STR],
|
|
237
|
+
[...monthNames0, 'Adar I', 'Adar II', NISAN_STR],
|
|
238
|
+
];
|
|
239
|
+
const edCache = new Map();
|
|
240
|
+
const EPOCH = -1373428;
|
|
241
|
+
// Avg year length in the cycle (19 solar years with 235 lunar months)
|
|
242
|
+
const AVG_HEBYEAR_DAYS = 365.24682220597794;
|
|
243
|
+
/**
|
|
244
|
+
* @private
|
|
245
|
+
*/
|
|
246
|
+
function assertNumber(n, name) {
|
|
247
|
+
if (typeof n !== 'number' || isNaN(n)) {
|
|
248
|
+
throw new TypeError(`param '${name}' not a number: ${n}`);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Converts Hebrew date to R.D. (Rata Die) fixed days.
|
|
253
|
+
* R.D. 1 is the imaginary date Monday, January 1, 1 on the Gregorian
|
|
254
|
+
* Calendar.
|
|
255
|
+
* @param year Hebrew year
|
|
256
|
+
* @param month Hebrew month
|
|
257
|
+
* @param day Hebrew date (1-30)
|
|
258
|
+
* @example
|
|
259
|
+
* const abs = hebrew2abs(5769, months.CHESHVAN, 15);
|
|
260
|
+
*/
|
|
261
|
+
function hebrew2abs(year, month, day) {
|
|
262
|
+
assertNumber(year, 'year');
|
|
263
|
+
assertNumber(month, 'month');
|
|
264
|
+
assertNumber(day, 'day');
|
|
265
|
+
if (year < 1) {
|
|
266
|
+
throw new RangeError(`hebrew2abs: invalid year ${year}`);
|
|
267
|
+
}
|
|
268
|
+
let tempabs = day;
|
|
269
|
+
if (month < TISHREI$2) {
|
|
270
|
+
for (let m = TISHREI$2; m <= monthsInYear(year); m++) {
|
|
271
|
+
tempabs += daysInMonth(m, year);
|
|
272
|
+
}
|
|
273
|
+
for (let m = NISAN$4; m < month; m++) {
|
|
274
|
+
tempabs += daysInMonth(m, year);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
for (let m = TISHREI$2; m < month; m++) {
|
|
279
|
+
tempabs += daysInMonth(m, year);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
return EPOCH + elapsedDays(year) + tempabs - 1;
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* @private
|
|
286
|
+
*/
|
|
287
|
+
function newYear(year) {
|
|
288
|
+
return EPOCH + elapsedDays(year);
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Converts absolute R.D. days to Hebrew date
|
|
292
|
+
* @param abs absolute R.D. days
|
|
293
|
+
*/
|
|
294
|
+
function abs2hebrew(abs) {
|
|
295
|
+
assertNumber(abs, 'abs');
|
|
296
|
+
abs = Math.trunc(abs);
|
|
297
|
+
if (abs <= EPOCH) {
|
|
298
|
+
throw new RangeError(`abs2hebrew: ${abs} is before epoch`);
|
|
299
|
+
}
|
|
300
|
+
// first, quickly approximate year
|
|
301
|
+
let year = Math.floor((abs - EPOCH) / AVG_HEBYEAR_DAYS);
|
|
302
|
+
while (newYear(year) <= abs) {
|
|
303
|
+
++year;
|
|
304
|
+
}
|
|
305
|
+
--year;
|
|
306
|
+
let month = abs < hebrew2abs(year, 1, 1) ? 7 : 1;
|
|
307
|
+
while (abs > hebrew2abs(year, month, daysInMonth(month, year))) {
|
|
308
|
+
++month;
|
|
309
|
+
}
|
|
310
|
+
const day = 1 + abs - hebrew2abs(year, month, 1);
|
|
311
|
+
return { yy: year, mm: month, dd: day };
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Returns true if Hebrew year is a leap year
|
|
315
|
+
* @param year Hebrew year
|
|
316
|
+
*/
|
|
317
|
+
function isLeapYear(year) {
|
|
318
|
+
return (1 + year * 7) % 19 < 7;
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Number of months in this Hebrew year (either 12 or 13 depending on leap year)
|
|
322
|
+
* @param year Hebrew year
|
|
323
|
+
*/
|
|
324
|
+
function monthsInYear(year) {
|
|
325
|
+
return 12 + +isLeapYear(year); // boolean is cast to 1 or 0
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Number of days in Hebrew month in a given year (29 or 30)
|
|
329
|
+
* @param month Hebrew month (e.g. months.TISHREI)
|
|
330
|
+
* @param year Hebrew year
|
|
331
|
+
*/
|
|
332
|
+
function daysInMonth(month, year) {
|
|
333
|
+
switch (month) {
|
|
334
|
+
case IYYAR$1:
|
|
335
|
+
case TAMUZ$1:
|
|
336
|
+
case ELUL$1:
|
|
337
|
+
case TEVET$2:
|
|
338
|
+
case ADAR_II$2:
|
|
339
|
+
return 29;
|
|
340
|
+
}
|
|
341
|
+
if ((month === ADAR_I$2 && !isLeapYear(year)) ||
|
|
342
|
+
(month === CHESHVAN$1 && !longCheshvan(year)) ||
|
|
343
|
+
(month === KISLEV$2 && shortKislev(year))) {
|
|
344
|
+
return 29;
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
return 30;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Returns a transliterated string name of Hebrew month in year,
|
|
352
|
+
* for example 'Elul' or 'Cheshvan'.
|
|
353
|
+
* @param month Hebrew month (e.g. months.TISHREI)
|
|
354
|
+
* @param year Hebrew year
|
|
355
|
+
*/
|
|
356
|
+
function getMonthName(month, year) {
|
|
357
|
+
assertNumber(month, 'month');
|
|
358
|
+
assertNumber(year, 'year');
|
|
359
|
+
if (month < 1 || month > 14) {
|
|
360
|
+
throw new TypeError(`bad monthNum: ${month}`);
|
|
361
|
+
}
|
|
362
|
+
return monthNames[+isLeapYear(year)][month];
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Days from sunday prior to start of Hebrew calendar to mean
|
|
366
|
+
* conjunction of Tishrei in Hebrew YEAR
|
|
367
|
+
* @param year Hebrew year
|
|
368
|
+
*/
|
|
369
|
+
function elapsedDays(year) {
|
|
370
|
+
const n = edCache.get(year);
|
|
371
|
+
if (typeof n === 'number') {
|
|
372
|
+
return n;
|
|
373
|
+
}
|
|
374
|
+
const elapsed = elapsedDays0(year);
|
|
375
|
+
edCache.set(year, elapsed);
|
|
376
|
+
return elapsed;
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Days from sunday prior to start of Hebrew calendar to mean
|
|
380
|
+
* conjunction of Tishrei in Hebrew YEAR
|
|
381
|
+
* @private
|
|
382
|
+
* @param year Hebrew year
|
|
383
|
+
*/
|
|
384
|
+
function elapsedDays0(year) {
|
|
385
|
+
const prevYear = year - 1;
|
|
386
|
+
const mElapsed = 235 * Math.floor(prevYear / 19) + // Months in complete 19 year lunar (Metonic) cycles so far
|
|
387
|
+
12 * (prevYear % 19) + // Regular months in this cycle
|
|
388
|
+
Math.floor(((prevYear % 19) * 7 + 1) / 19); // Leap months this cycle
|
|
389
|
+
const pElapsed = 204 + 793 * (mElapsed % 1080);
|
|
390
|
+
const hElapsed = 5 +
|
|
391
|
+
12 * mElapsed +
|
|
392
|
+
793 * Math.floor(mElapsed / 1080) +
|
|
393
|
+
Math.floor(pElapsed / 1080);
|
|
394
|
+
const parts = (pElapsed % 1080) + 1080 * (hElapsed % 24);
|
|
395
|
+
const day = 1 + 29 * mElapsed + Math.floor(hElapsed / 24);
|
|
396
|
+
let altDay = day;
|
|
397
|
+
if (parts >= 19440 ||
|
|
398
|
+
(2 === day % 7 && parts >= 9924 && !isLeapYear(year)) ||
|
|
399
|
+
(1 === day % 7 && parts >= 16789 && isLeapYear(prevYear))) {
|
|
400
|
+
altDay++;
|
|
401
|
+
}
|
|
402
|
+
if (altDay % 7 === 0 || altDay % 7 === 3 || altDay % 7 === 5) {
|
|
403
|
+
return altDay + 1;
|
|
404
|
+
}
|
|
405
|
+
else {
|
|
406
|
+
return altDay;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Number of days in the hebrew YEAR.
|
|
411
|
+
* A common Hebrew calendar year can have a length of 353, 354 or 355 days
|
|
412
|
+
* A leap Hebrew calendar year can have a length of 383, 384 or 385 days
|
|
413
|
+
* @param year Hebrew year
|
|
414
|
+
*/
|
|
415
|
+
function daysInYear(year) {
|
|
416
|
+
return elapsedDays(year + 1) - elapsedDays(year);
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* true if Cheshvan is long in Hebrew year
|
|
420
|
+
* @param year Hebrew year
|
|
421
|
+
*/
|
|
422
|
+
function longCheshvan(year) {
|
|
423
|
+
return daysInYear(year) % 10 === 5;
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* true if Kislev is short in Hebrew year
|
|
427
|
+
* @param year Hebrew year
|
|
428
|
+
*/
|
|
429
|
+
function shortKislev(year) {
|
|
430
|
+
return daysInYear(year) % 10 === 3;
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* Converts Hebrew month string name to numeric
|
|
434
|
+
* @param monthName monthName
|
|
435
|
+
*/
|
|
436
|
+
function monthFromName(monthName) {
|
|
437
|
+
if (typeof monthName === 'number') {
|
|
438
|
+
if (isNaN(monthName) || monthName < 1 || monthName > 14) {
|
|
439
|
+
throw new RangeError(`bad monthName: ${monthName}`);
|
|
440
|
+
}
|
|
441
|
+
return monthName;
|
|
442
|
+
}
|
|
443
|
+
let c = monthName.trim().toLowerCase();
|
|
444
|
+
// If Hebrew month starts with a bet (for example `בתמוז`) then ignore it
|
|
445
|
+
if (c[0] === 'ב') {
|
|
446
|
+
c = c.substring(1);
|
|
447
|
+
}
|
|
448
|
+
/*
|
|
449
|
+
the Hebrew months are unique to their second letter
|
|
450
|
+
N Nisan (November?)
|
|
451
|
+
I Iyyar
|
|
452
|
+
E Elul
|
|
453
|
+
C Cheshvan
|
|
454
|
+
K Kislev
|
|
455
|
+
1 1Adar
|
|
456
|
+
2 2Adar
|
|
457
|
+
Si Sh Sivan, Shvat
|
|
458
|
+
Ta Ti Te Tamuz, Tishrei, Tevet
|
|
459
|
+
Av Ad Av, Adar
|
|
460
|
+
|
|
461
|
+
אב אד אי אל אב אדר אייר אלול
|
|
462
|
+
ח חשון
|
|
463
|
+
ט טבת
|
|
464
|
+
כ כסלו
|
|
465
|
+
נ ניסן
|
|
466
|
+
ס סיון
|
|
467
|
+
ש שבט
|
|
468
|
+
תמ תש תמוז תשרי
|
|
469
|
+
*/
|
|
470
|
+
switch (c[0]) {
|
|
471
|
+
case 'n':
|
|
472
|
+
case 'נ':
|
|
473
|
+
if (c[1] === 'o') {
|
|
474
|
+
break; /* this catches "november" */
|
|
475
|
+
}
|
|
476
|
+
return NISAN$4;
|
|
477
|
+
case 'i':
|
|
478
|
+
return IYYAR$1;
|
|
479
|
+
case 'e':
|
|
480
|
+
return ELUL$1;
|
|
481
|
+
case 'c':
|
|
482
|
+
case 'ח':
|
|
483
|
+
return CHESHVAN$1;
|
|
484
|
+
case 'k':
|
|
485
|
+
case 'כ':
|
|
486
|
+
return KISLEV$2;
|
|
487
|
+
case 's':
|
|
488
|
+
switch (c[1]) {
|
|
489
|
+
case 'i':
|
|
490
|
+
return SIVAN$1;
|
|
491
|
+
case 'h':
|
|
492
|
+
return SHVAT$1;
|
|
493
|
+
}
|
|
494
|
+
break;
|
|
495
|
+
case 't':
|
|
496
|
+
switch (c[1]) {
|
|
497
|
+
case 'a':
|
|
498
|
+
return TAMUZ$1;
|
|
499
|
+
case 'i':
|
|
500
|
+
return TISHREI$2;
|
|
501
|
+
case 'e':
|
|
502
|
+
return TEVET$2;
|
|
503
|
+
}
|
|
504
|
+
break;
|
|
505
|
+
case 'a':
|
|
506
|
+
switch (c[1]) {
|
|
507
|
+
case 'v':
|
|
508
|
+
return AV$1;
|
|
509
|
+
case 'd':
|
|
510
|
+
if (/(1|[^i]i|a|א)$/i.test(monthName)) {
|
|
511
|
+
return ADAR_I$2;
|
|
512
|
+
}
|
|
513
|
+
return ADAR_II$2; // else assume sheini
|
|
514
|
+
}
|
|
515
|
+
break;
|
|
516
|
+
case 'ס':
|
|
517
|
+
return SIVAN$1;
|
|
518
|
+
case 'ט':
|
|
519
|
+
return TEVET$2;
|
|
520
|
+
case 'ש':
|
|
521
|
+
return SHVAT$1;
|
|
522
|
+
case 'א':
|
|
523
|
+
switch (c[1]) {
|
|
524
|
+
case 'ב':
|
|
525
|
+
return AV$1;
|
|
526
|
+
case 'ד':
|
|
527
|
+
if (/(1|[^i]i|a|א)$/i.test(monthName)) {
|
|
528
|
+
return ADAR_I$2;
|
|
529
|
+
}
|
|
530
|
+
return ADAR_II$2; // else assume sheini
|
|
531
|
+
case 'י':
|
|
532
|
+
return IYYAR$1;
|
|
533
|
+
case 'ל':
|
|
534
|
+
return ELUL$1;
|
|
535
|
+
}
|
|
536
|
+
break;
|
|
537
|
+
case 'ת':
|
|
538
|
+
switch (c[1]) {
|
|
539
|
+
case 'מ':
|
|
540
|
+
return TAMUZ$1;
|
|
541
|
+
case 'ש':
|
|
542
|
+
return TISHREI$2;
|
|
543
|
+
}
|
|
544
|
+
break;
|
|
545
|
+
}
|
|
546
|
+
throw new RangeError(`bad monthName: ${monthName}`);
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
/*! @hebcal/hdate v0.14.2, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
|
|
550
|
+
|
|
551
|
+
const NISAN$3 = months.NISAN;
|
|
552
|
+
const CHESHVAN = months.CHESHVAN;
|
|
553
|
+
const KISLEV$1 = months.KISLEV;
|
|
554
|
+
const TEVET$1 = months.TEVET;
|
|
555
|
+
const SHVAT = months.SHVAT;
|
|
556
|
+
const ADAR_I$1 = months.ADAR_I;
|
|
557
|
+
const ADAR_II$1 = months.ADAR_II;
|
|
558
|
+
/**
|
|
559
|
+
* Returns true if the object is a SimpleHebrewDate
|
|
560
|
+
* @private
|
|
561
|
+
*/
|
|
562
|
+
function isSimpleHebrewDate$1(obj) {
|
|
563
|
+
return (typeof obj === 'object' &&
|
|
564
|
+
obj !== null &&
|
|
565
|
+
typeof obj.yy === 'number' &&
|
|
566
|
+
typeof obj.mm === 'number' &&
|
|
567
|
+
typeof obj.dd === 'number');
|
|
568
|
+
}
|
|
569
|
+
/**
|
|
570
|
+
* @private
|
|
571
|
+
*/
|
|
572
|
+
function toSimpleHebrewDate(obj) {
|
|
573
|
+
if (isSimpleHebrewDate$1(obj)) {
|
|
574
|
+
return obj;
|
|
575
|
+
}
|
|
576
|
+
else if (isDate(obj)) {
|
|
577
|
+
const abs = greg2abs(obj);
|
|
578
|
+
return abs2hebrew(abs);
|
|
579
|
+
}
|
|
580
|
+
else {
|
|
581
|
+
// typeof obj === 'number'
|
|
582
|
+
return abs2hebrew(obj);
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
function getYahrzeitHD(hyear, date) {
|
|
586
|
+
let hDeath = toSimpleHebrewDate(date);
|
|
587
|
+
if (hyear <= hDeath.yy) {
|
|
588
|
+
// Hebrew year ${hyear} occurs on or before original date in ${hDeath.yy}
|
|
589
|
+
return undefined;
|
|
590
|
+
}
|
|
591
|
+
if (hDeath.mm === CHESHVAN &&
|
|
592
|
+
hDeath.dd === 30 &&
|
|
593
|
+
!longCheshvan(hDeath.yy + 1)) {
|
|
594
|
+
// If it's Heshvan 30 it depends on the first anniversary;
|
|
595
|
+
// if that was not Heshvan 30, use the day before Kislev 1.
|
|
596
|
+
hDeath = abs2hebrew(hebrew2abs(hyear, KISLEV$1, 1) - 1);
|
|
597
|
+
}
|
|
598
|
+
else if (hDeath.mm === KISLEV$1 &&
|
|
599
|
+
hDeath.dd === 30 &&
|
|
600
|
+
shortKislev(hDeath.yy + 1)) {
|
|
601
|
+
// If it's Kislev 30 it depends on the first anniversary;
|
|
602
|
+
// if that was not Kislev 30, use the day before Teveth 1.
|
|
603
|
+
hDeath = abs2hebrew(hebrew2abs(hyear, TEVET$1, 1) - 1);
|
|
604
|
+
}
|
|
605
|
+
else if (hDeath.mm === ADAR_II$1) {
|
|
606
|
+
// If it's Adar II, use the same day in last month of year (Adar or Adar II).
|
|
607
|
+
hDeath.mm = monthsInYear(hyear);
|
|
608
|
+
}
|
|
609
|
+
else if (hDeath.mm === ADAR_I$1 && hDeath.dd === 30 && !isLeapYear(hyear)) {
|
|
610
|
+
// If it's the 30th in Adar I and year is not a leap year
|
|
611
|
+
// (so Adar has only 29 days), use the last day in Shevat.
|
|
612
|
+
hDeath.dd = 30;
|
|
613
|
+
hDeath.mm = SHVAT;
|
|
614
|
+
}
|
|
615
|
+
// In all other cases, use the normal anniversary of the date of death.
|
|
616
|
+
// advance day to rosh chodesh if needed
|
|
617
|
+
if (hDeath.mm === CHESHVAN && hDeath.dd === 30 && !longCheshvan(hyear)) {
|
|
618
|
+
hDeath.mm = KISLEV$1;
|
|
619
|
+
hDeath.dd = 1;
|
|
620
|
+
}
|
|
621
|
+
else if (hDeath.mm === KISLEV$1 && hDeath.dd === 30 && shortKislev(hyear)) {
|
|
622
|
+
hDeath.mm = TEVET$1;
|
|
623
|
+
hDeath.dd = 1;
|
|
624
|
+
}
|
|
625
|
+
hDeath.yy = hyear;
|
|
626
|
+
return hDeath;
|
|
627
|
+
}
|
|
628
|
+
function getBirthdayHD(hyear, date) {
|
|
629
|
+
const orig = toSimpleHebrewDate(date);
|
|
630
|
+
const origYear = orig.yy;
|
|
631
|
+
if (hyear === origYear) {
|
|
632
|
+
return orig;
|
|
633
|
+
}
|
|
634
|
+
else if (hyear < origYear) {
|
|
635
|
+
// Hebrew year ${hyear} occurs on or before original date in ${origYear}
|
|
636
|
+
return undefined;
|
|
637
|
+
}
|
|
638
|
+
const isOrigLeap = isLeapYear(origYear);
|
|
639
|
+
let month = orig.mm;
|
|
640
|
+
let day = orig.dd;
|
|
641
|
+
if ((month === ADAR_I$1 && !isOrigLeap) || (month === ADAR_II$1 && isOrigLeap)) {
|
|
642
|
+
month = monthsInYear(hyear);
|
|
643
|
+
}
|
|
644
|
+
else if (month === CHESHVAN && day === 30 && !longCheshvan(hyear)) {
|
|
645
|
+
month = KISLEV$1;
|
|
646
|
+
day = 1;
|
|
647
|
+
}
|
|
648
|
+
else if (month === KISLEV$1 && day === 30 && shortKislev(hyear)) {
|
|
649
|
+
month = TEVET$1;
|
|
650
|
+
day = 1;
|
|
651
|
+
}
|
|
652
|
+
else if (month === ADAR_I$1 &&
|
|
653
|
+
day === 30 &&
|
|
654
|
+
isOrigLeap &&
|
|
655
|
+
!isLeapYear(hyear)) {
|
|
656
|
+
month = NISAN$3;
|
|
657
|
+
day = 1;
|
|
658
|
+
}
|
|
659
|
+
return { yy: hyear, mm: month, dd: day };
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
/*! @hebcal/hdate v0.14.2, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
|
|
663
|
+
const GERESH = '׳';
|
|
664
|
+
const GERSHAYIM = '״';
|
|
665
|
+
const heb2num = {
|
|
666
|
+
א: 1,
|
|
667
|
+
ב: 2,
|
|
668
|
+
ג: 3,
|
|
669
|
+
ד: 4,
|
|
670
|
+
ה: 5,
|
|
671
|
+
ו: 6,
|
|
672
|
+
ז: 7,
|
|
673
|
+
ח: 8,
|
|
674
|
+
ט: 9,
|
|
675
|
+
י: 10,
|
|
676
|
+
כ: 20,
|
|
677
|
+
ל: 30,
|
|
678
|
+
מ: 40,
|
|
679
|
+
נ: 50,
|
|
680
|
+
ס: 60,
|
|
681
|
+
ע: 70,
|
|
682
|
+
פ: 80,
|
|
683
|
+
צ: 90,
|
|
684
|
+
ק: 100,
|
|
685
|
+
ר: 200,
|
|
686
|
+
ש: 300,
|
|
687
|
+
ת: 400,
|
|
688
|
+
};
|
|
689
|
+
const num2heb = {};
|
|
690
|
+
for (const [key, val] of Object.entries(heb2num)) {
|
|
691
|
+
num2heb[val] = key;
|
|
692
|
+
}
|
|
693
|
+
function num2digits(num) {
|
|
694
|
+
const digits = [];
|
|
695
|
+
while (num > 0) {
|
|
696
|
+
if (num === 15 || num === 16) {
|
|
697
|
+
digits.push(9);
|
|
698
|
+
digits.push(num - 9);
|
|
699
|
+
break;
|
|
700
|
+
}
|
|
701
|
+
let incr = 100;
|
|
702
|
+
let i;
|
|
703
|
+
for (i = 400; i > num; i -= incr) {
|
|
704
|
+
if (i === incr) {
|
|
705
|
+
incr = incr / 10;
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
digits.push(i);
|
|
709
|
+
num -= i;
|
|
710
|
+
}
|
|
711
|
+
return digits;
|
|
712
|
+
}
|
|
713
|
+
/**
|
|
714
|
+
* Converts a numerical value to a string of Hebrew letters.
|
|
715
|
+
*
|
|
716
|
+
* When specifying years of the Hebrew calendar in the present millennium,
|
|
717
|
+
* we omit the thousands (which is presently 5 [ה]).
|
|
718
|
+
* @example
|
|
719
|
+
* gematriya(5774) // 'תשע״ד' - cropped to 774
|
|
720
|
+
* gematriya(25) // 'כ״ה'
|
|
721
|
+
* gematriya(60) // 'ס׳'
|
|
722
|
+
* gematriya(3761) // 'ג׳תשס״א'
|
|
723
|
+
* gematriya(1123) // 'א׳קכ״ג'
|
|
724
|
+
*/
|
|
725
|
+
function gematriya(num) {
|
|
726
|
+
const num1 = parseInt(num, 10);
|
|
727
|
+
if (!num1 || num1 < 0) {
|
|
728
|
+
throw new TypeError(`invalid number: ${num}`);
|
|
729
|
+
}
|
|
730
|
+
let str = '';
|
|
731
|
+
const thousands = Math.floor(num1 / 1000);
|
|
732
|
+
if (thousands > 0 && thousands !== 5) {
|
|
733
|
+
const tdigits = num2digits(thousands);
|
|
734
|
+
for (const tdig of tdigits) {
|
|
735
|
+
str += num2heb[tdig];
|
|
736
|
+
}
|
|
737
|
+
str += GERESH;
|
|
738
|
+
}
|
|
739
|
+
const digits = num2digits(num1 % 1000);
|
|
740
|
+
if (digits.length === 1) {
|
|
741
|
+
return str + num2heb[digits[0]] + GERESH;
|
|
742
|
+
}
|
|
743
|
+
for (let i = 0; i < digits.length; i++) {
|
|
744
|
+
if (i + 1 === digits.length) {
|
|
745
|
+
str += GERSHAYIM;
|
|
746
|
+
}
|
|
747
|
+
str += num2heb[digits[i]];
|
|
748
|
+
}
|
|
749
|
+
return str;
|
|
750
|
+
}
|
|
751
|
+
/**
|
|
752
|
+
* Converts a string of Hebrew letters to a numerical value.
|
|
753
|
+
*
|
|
754
|
+
* Only considers the value of Hebrew letters `א` through `ת`.
|
|
755
|
+
* Ignores final Hebrew letters such as `ך` (kaf sofit) or `ם` (mem sofit)
|
|
756
|
+
* and vowels (nekudot).
|
|
757
|
+
*/
|
|
758
|
+
function gematriyaStrToNum(str) {
|
|
759
|
+
let num = 0;
|
|
760
|
+
const gereshIdx = str.indexOf(GERESH);
|
|
761
|
+
if (gereshIdx !== -1 && gereshIdx !== str.length - 1) {
|
|
762
|
+
const thousands = str.substring(0, gereshIdx);
|
|
763
|
+
num += gematriyaStrToNum(thousands) * 1000;
|
|
764
|
+
str = str.substring(gereshIdx);
|
|
765
|
+
}
|
|
766
|
+
for (const ch of str) {
|
|
767
|
+
const n = heb2num[ch];
|
|
768
|
+
if (typeof n === 'number') {
|
|
769
|
+
num += n;
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
return num;
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
/*! @hebcal/hdate v0.14.2, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
|
|
776
|
+
|
|
777
|
+
/**
|
|
778
|
+
* Calculates the molad for a Hebrew month
|
|
779
|
+
*/
|
|
780
|
+
function molad(year, month) {
|
|
781
|
+
let m_adj = month - 7;
|
|
782
|
+
if (m_adj < 0) {
|
|
783
|
+
m_adj += monthsInYear(year);
|
|
784
|
+
}
|
|
785
|
+
const mElapsed = 235 * Math.floor((year - 1) / 19) + // Months in complete 19 year lunar (Metonic) cycles so far
|
|
786
|
+
12 * ((year - 1) % 19) + // Regular months in this cycle
|
|
787
|
+
Math.floor((7 * ((year - 1) % 19) + 1) / 19) + // Leap months this cycle
|
|
788
|
+
m_adj; // add elapsed months till the start of the molad of the month
|
|
789
|
+
const pElapsed = 204 + Math.floor(793 * (mElapsed % 1080));
|
|
790
|
+
const hElapsed = 5 +
|
|
791
|
+
12 * mElapsed +
|
|
792
|
+
793 * Math.floor(mElapsed / 1080) +
|
|
793
|
+
Math.floor(pElapsed / 1080) -
|
|
794
|
+
6;
|
|
795
|
+
const parts = (pElapsed % 1080) + 1080 * (hElapsed % 24);
|
|
796
|
+
const chalakim = parts % 1080;
|
|
797
|
+
const day = 1 + 29 * mElapsed + Math.floor(hElapsed / 24);
|
|
798
|
+
return {
|
|
799
|
+
year,
|
|
800
|
+
month,
|
|
801
|
+
dayOfWeek: day % 7,
|
|
802
|
+
hour: hElapsed % 24,
|
|
803
|
+
minutes: Math.floor(chalakim / 18),
|
|
804
|
+
chalakim: chalakim % 18,
|
|
805
|
+
};
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
/*! @hebcal/hdate v0.14.2, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
|
|
809
|
+
/**
|
|
810
|
+
* Formats a number with leading zeros so the resulting string is 4 digits long.
|
|
811
|
+
* Similar to `string.padStart(4, '0')` but will also format
|
|
812
|
+
* negative numbers similar to how the JavaScript date formats
|
|
813
|
+
* negative year numbers (e.g. `-37` is formatted as `-000037`).
|
|
814
|
+
*/
|
|
815
|
+
function pad4(num) {
|
|
816
|
+
if (num < 0) {
|
|
817
|
+
return '-00' + pad4(-num);
|
|
818
|
+
}
|
|
819
|
+
else if (num < 10) {
|
|
820
|
+
return '000' + num;
|
|
821
|
+
}
|
|
822
|
+
else if (num < 100) {
|
|
823
|
+
return '00' + num;
|
|
824
|
+
}
|
|
825
|
+
else if (num < 1000) {
|
|
826
|
+
return '0' + num;
|
|
827
|
+
}
|
|
828
|
+
return String(num);
|
|
829
|
+
}
|
|
830
|
+
/**
|
|
831
|
+
* Formats a number with leading zeros so the resulting string is 2 digits long.
|
|
832
|
+
* Similar to `string.padStart(2, '0')`.
|
|
833
|
+
*/
|
|
834
|
+
function pad2(num) {
|
|
835
|
+
if (num >= 0 && num < 10) {
|
|
836
|
+
return '0' + num;
|
|
837
|
+
}
|
|
838
|
+
return String(num);
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
/*! @hebcal/hdate v0.14.2, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
|
|
842
|
+
|
|
843
|
+
const _formatters = new Map();
|
|
844
|
+
/**
|
|
845
|
+
* @private
|
|
846
|
+
*/
|
|
847
|
+
function getFormatter$1(tzid) {
|
|
848
|
+
const fmt = _formatters.get(tzid);
|
|
849
|
+
if (fmt)
|
|
850
|
+
return fmt;
|
|
851
|
+
const f = new Intl.DateTimeFormat('en-US', {
|
|
852
|
+
year: 'numeric',
|
|
853
|
+
month: '2-digit',
|
|
854
|
+
day: '2-digit',
|
|
855
|
+
hour: '2-digit',
|
|
856
|
+
minute: '2-digit',
|
|
857
|
+
second: '2-digit',
|
|
858
|
+
hour12: false,
|
|
859
|
+
timeZone: tzid,
|
|
860
|
+
});
|
|
861
|
+
_formatters.set(tzid, f);
|
|
862
|
+
return f;
|
|
863
|
+
}
|
|
864
|
+
const dateFormatRegex = /^(\d+).(\d+).(\d+),?\s+(\d+).(\d+).(\d+)/;
|
|
865
|
+
/**
|
|
866
|
+
* Returns a string similar to `Date.toISOString()` but in the
|
|
867
|
+
* timezone `tzid`. Contrary to the typical meaning of `Z` at the end
|
|
868
|
+
* of the string, this is not actually a UTC date.
|
|
869
|
+
*/
|
|
870
|
+
function getPseudoISO(tzid, date) {
|
|
871
|
+
const str = getFormatter$1(tzid).format(date);
|
|
872
|
+
const m = dateFormatRegex.exec(str);
|
|
873
|
+
if (m === null) {
|
|
874
|
+
throw new Error(`Unable to parse formatted string: ${str}`);
|
|
875
|
+
}
|
|
876
|
+
let hour = m[4];
|
|
877
|
+
if (hour === '24') {
|
|
878
|
+
hour = '00';
|
|
879
|
+
}
|
|
880
|
+
m[3] = pad4(parseInt(m[3], 10));
|
|
881
|
+
return `${m[3]}-${m[1]}-${m[2]}T${hour}:${m[5]}:${m[6]}Z`;
|
|
882
|
+
}
|
|
883
|
+
/**
|
|
884
|
+
* Returns number of minutes `tzid` is offset from UTC on date `date`.
|
|
885
|
+
*/
|
|
886
|
+
function getTimezoneOffset(tzid, date) {
|
|
887
|
+
const utcStr = getPseudoISO('UTC', date);
|
|
888
|
+
const localStr = getPseudoISO(tzid, date);
|
|
889
|
+
const diffMs = new Date(utcStr).getTime() - new Date(localStr).getTime();
|
|
890
|
+
return Math.ceil(diffMs / 1000 / 60);
|
|
891
|
+
}
|
|
892
|
+
/**
|
|
893
|
+
* Returns YYYY-MM-DD in the local timezone
|
|
894
|
+
*/
|
|
895
|
+
function isoDateString(dt) {
|
|
896
|
+
return (pad4(dt.getFullYear()) +
|
|
897
|
+
'-' +
|
|
898
|
+
pad2(dt.getMonth() + 1) +
|
|
899
|
+
'-' +
|
|
900
|
+
pad2(dt.getDate()));
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
/*! @hebcal/hdate v0.14.2, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
|
|
904
|
+
var poAshkenazi$1 = { "headers": { "plural-forms": "nplurals=2; plural=(n > 1);", "language": "en_CA@ashkenazi" }, "contexts": { "": { "Tevet": ["Teves"] } } };
|
|
905
|
+
|
|
906
|
+
/*! @hebcal/hdate v0.14.2, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
|
|
907
|
+
var poHe$1 = { "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": ["תַּמּוּז"], "Tevet": ["טֵבֵת"], "Tishrei": ["תִּשְׁרֵי"] } } };
|
|
908
|
+
|
|
909
|
+
/*! @hebcal/hdate v0.14.2, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
|
|
910
|
+
|
|
911
|
+
const noopLocale = {
|
|
912
|
+
headers: { 'plural-forms': 'nplurals=2; plural=(n!=1);' },
|
|
913
|
+
contexts: { '': {} },
|
|
914
|
+
};
|
|
915
|
+
const alias = {
|
|
916
|
+
h: 'he',
|
|
917
|
+
a: 'ashkenazi',
|
|
918
|
+
s: 'en',
|
|
919
|
+
'': 'en',
|
|
920
|
+
};
|
|
921
|
+
/** @private */
|
|
922
|
+
const locales = new Map();
|
|
923
|
+
/** @private */
|
|
924
|
+
let activeLocale;
|
|
925
|
+
/** @private */
|
|
926
|
+
let activeName;
|
|
927
|
+
/** @private */
|
|
928
|
+
function getEnOrdinal(n) {
|
|
929
|
+
const s = ['th', 'st', 'nd', 'rd'];
|
|
930
|
+
const v = n % 100;
|
|
931
|
+
return n + (s[(v - 20) % 10] || s[v] || s[0]);
|
|
932
|
+
}
|
|
933
|
+
/** @private */
|
|
934
|
+
function checkLocale(locale) {
|
|
935
|
+
if (typeof locale !== 'string') {
|
|
936
|
+
throw new TypeError(`Invalid locale name: ${locale}`);
|
|
937
|
+
}
|
|
938
|
+
return locale.toLowerCase();
|
|
939
|
+
}
|
|
940
|
+
/** @private */
|
|
941
|
+
function getExistingLocale(locale) {
|
|
942
|
+
const locale1 = checkLocale(locale);
|
|
943
|
+
const loc = locales.get(locale1);
|
|
944
|
+
if (!loc) {
|
|
945
|
+
throw new RangeError(`Locale '${locale}' not found`);
|
|
946
|
+
}
|
|
947
|
+
return loc;
|
|
948
|
+
}
|
|
949
|
+
/**
|
|
950
|
+
* A locale in Hebcal is used for translations/transliterations of
|
|
951
|
+
* holidays. `@hebcal/hdate` supports four locales by default
|
|
952
|
+
* * `en` - default, Sephardic transliterations (e.g. "Shabbat")
|
|
953
|
+
* * `ashkenazi` - Ashkenazi transliterations (e.g. "Shabbos")
|
|
954
|
+
* * `he` - Hebrew (e.g. "שַׁבָּת")
|
|
955
|
+
* * `he-x-NoNikud` - Hebrew without nikud (e.g. "שבת")
|
|
956
|
+
*/
|
|
957
|
+
class Locale {
|
|
958
|
+
/**
|
|
959
|
+
* Returns translation only if `locale` offers a non-empty translation for `id`.
|
|
960
|
+
* Otherwise, returns `undefined`.
|
|
961
|
+
* @param id Message ID to translate
|
|
962
|
+
* @param [locale] Optional locale name (i.e: `'he'`, `'fr'`). Defaults to active locale.
|
|
963
|
+
*/
|
|
964
|
+
static lookupTranslation(id, locale) {
|
|
965
|
+
const loc = (typeof locale === 'string' && locales.get(locale.toLowerCase())) ||
|
|
966
|
+
activeLocale;
|
|
967
|
+
const array = loc[id];
|
|
968
|
+
if ((array === null || array === void 0 ? void 0 : array.length) && array[0].length) {
|
|
969
|
+
return array[0];
|
|
970
|
+
}
|
|
971
|
+
return undefined;
|
|
972
|
+
}
|
|
973
|
+
/**
|
|
974
|
+
* By default, if no translation was found, returns `id`.
|
|
975
|
+
* @param id Message ID to translate
|
|
976
|
+
* @param [locale] Optional locale name (i.e: `'he'`, `'fr'`). Defaults to active locale.
|
|
977
|
+
*/
|
|
978
|
+
static gettext(id, locale) {
|
|
979
|
+
const text = this.lookupTranslation(id, locale);
|
|
980
|
+
if (typeof text === 'undefined') {
|
|
981
|
+
return id;
|
|
982
|
+
}
|
|
983
|
+
return text;
|
|
984
|
+
}
|
|
985
|
+
/**
|
|
986
|
+
* Register locale translations.
|
|
987
|
+
* @param locale Locale name (i.e.: `'he'`, `'fr'`)
|
|
988
|
+
* @param data parsed data from a `.po` file.
|
|
989
|
+
*/
|
|
990
|
+
static addLocale(locale, data) {
|
|
991
|
+
locale = checkLocale(locale);
|
|
992
|
+
if (typeof data.contexts !== 'object' ||
|
|
993
|
+
typeof data.contexts[''] !== 'object') {
|
|
994
|
+
throw new TypeError(`Locale '${locale}' invalid compact format`);
|
|
995
|
+
}
|
|
996
|
+
locales.set(locale, data.contexts['']);
|
|
997
|
+
}
|
|
998
|
+
/**
|
|
999
|
+
* Adds a translation to `locale`, replacing any previous translation.
|
|
1000
|
+
* @param locale Locale name (i.e: `'he'`, `'fr'`).
|
|
1001
|
+
* @param id Message ID to translate
|
|
1002
|
+
* @param translation Translation text
|
|
1003
|
+
*/
|
|
1004
|
+
static addTranslation(locale, id, translation) {
|
|
1005
|
+
const loc = getExistingLocale(locale);
|
|
1006
|
+
if (typeof id !== 'string' || id.length === 0) {
|
|
1007
|
+
throw new TypeError(`Invalid id string: ${id}`);
|
|
1008
|
+
}
|
|
1009
|
+
const isArray = Array.isArray(translation);
|
|
1010
|
+
if (isArray) {
|
|
1011
|
+
const t0 = translation[0];
|
|
1012
|
+
if (typeof t0 !== 'string' || t0.length === 0) {
|
|
1013
|
+
throw new TypeError(`Invalid translation array: ${translation}`);
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
else if (typeof translation !== 'string') {
|
|
1017
|
+
throw new TypeError(`Invalid translation string: ${translation}`);
|
|
1018
|
+
}
|
|
1019
|
+
loc[id] = isArray ? translation : [translation];
|
|
1020
|
+
}
|
|
1021
|
+
/**
|
|
1022
|
+
* Adds multiple translations to `locale`, replacing any previous translations.
|
|
1023
|
+
* @param locale Locale name (i.e: `'he'`, `'fr'`).
|
|
1024
|
+
* @param data parsed data from a `.po` file.
|
|
1025
|
+
*/
|
|
1026
|
+
static addTranslations(locale, data) {
|
|
1027
|
+
const loc = getExistingLocale(locale);
|
|
1028
|
+
if (typeof data.contexts !== 'object' ||
|
|
1029
|
+
typeof data.contexts[''] !== 'object') {
|
|
1030
|
+
throw new TypeError(`Locale '${locale}' invalid compact format`);
|
|
1031
|
+
}
|
|
1032
|
+
const ctx = data.contexts[''];
|
|
1033
|
+
Object.assign(loc, ctx);
|
|
1034
|
+
}
|
|
1035
|
+
/**
|
|
1036
|
+
* Activates a locale. Throws an error if the locale has not been previously added.
|
|
1037
|
+
* After setting the locale to be used, all strings marked for translations
|
|
1038
|
+
* will be represented by the corresponding translation in the specified locale.
|
|
1039
|
+
* @param locale Locale name (i.e: `'he'`, `'fr'`)
|
|
1040
|
+
* @deprecated
|
|
1041
|
+
*/
|
|
1042
|
+
static useLocale(locale) {
|
|
1043
|
+
const locale0 = checkLocale(locale);
|
|
1044
|
+
const obj = getExistingLocale(locale0);
|
|
1045
|
+
activeName = alias[locale0] || locale0;
|
|
1046
|
+
activeLocale = obj;
|
|
1047
|
+
return activeLocale;
|
|
1048
|
+
}
|
|
1049
|
+
/**
|
|
1050
|
+
* Returns the name of the active locale (i.e. 'he', 'ashkenazi', 'fr')
|
|
1051
|
+
* @deprecated
|
|
1052
|
+
*/
|
|
1053
|
+
static getLocaleName() {
|
|
1054
|
+
return activeName;
|
|
1055
|
+
}
|
|
1056
|
+
/**
|
|
1057
|
+
* Returns the names of registered locales
|
|
1058
|
+
*/
|
|
1059
|
+
static getLocaleNames() {
|
|
1060
|
+
const keys = Array.from(locales.keys());
|
|
1061
|
+
return keys.sort((a, b) => a.localeCompare(b));
|
|
1062
|
+
}
|
|
1063
|
+
/**
|
|
1064
|
+
* Renders a number in ordinal, such as 1st, 2nd or 3rd
|
|
1065
|
+
* @param [locale] Optional locale name (i.e: `'he'`, `'fr'`). Defaults to active locale.
|
|
1066
|
+
*/
|
|
1067
|
+
static ordinal(n, locale) {
|
|
1068
|
+
const locale1 = locale === null || locale === void 0 ? void 0 : locale.toLowerCase();
|
|
1069
|
+
const locale0 = locale1 || activeName;
|
|
1070
|
+
if (!locale0) {
|
|
1071
|
+
return getEnOrdinal(n);
|
|
1072
|
+
}
|
|
1073
|
+
switch (locale0) {
|
|
1074
|
+
case 'en':
|
|
1075
|
+
case 's':
|
|
1076
|
+
case 'a':
|
|
1077
|
+
return getEnOrdinal(n);
|
|
1078
|
+
case 'es':
|
|
1079
|
+
return n + 'º';
|
|
1080
|
+
case 'h':
|
|
1081
|
+
case 'he':
|
|
1082
|
+
case 'he-x-nonikud':
|
|
1083
|
+
return String(n);
|
|
1084
|
+
}
|
|
1085
|
+
if (locale0.startsWith('ashkenazi')) {
|
|
1086
|
+
return getEnOrdinal(n);
|
|
1087
|
+
}
|
|
1088
|
+
return n + '.';
|
|
1089
|
+
}
|
|
1090
|
+
/**
|
|
1091
|
+
* Removes nekudot from Hebrew string
|
|
1092
|
+
*/
|
|
1093
|
+
static hebrewStripNikkud(str) {
|
|
1094
|
+
const a = str.normalize();
|
|
1095
|
+
// now strip out niqqud and trope
|
|
1096
|
+
return a.replace(/[\u0590-\u05bd]/g, '').replace(/[\u05bf-\u05c7]/g, '');
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
Locale.addLocale('en', noopLocale);
|
|
1100
|
+
Locale.addLocale('s', noopLocale);
|
|
1101
|
+
Locale.addLocale('', noopLocale);
|
|
1102
|
+
Locale.useLocale('en');
|
|
1103
|
+
/* Ashkenazic transliterations */
|
|
1104
|
+
Locale.addLocale('ashkenazi', poAshkenazi$1);
|
|
1105
|
+
Locale.addLocale('a', poAshkenazi$1);
|
|
1106
|
+
/* Hebrew with nikkud */
|
|
1107
|
+
Locale.addLocale('he', poHe$1);
|
|
1108
|
+
Locale.addLocale('h', poHe$1);
|
|
1109
|
+
/* Hebrew without nikkud */
|
|
1110
|
+
const heStrs$1 = poHe$1.contexts[''];
|
|
1111
|
+
const heNoNikud$1 = {};
|
|
1112
|
+
for (const [key, val] of Object.entries(heStrs$1)) {
|
|
1113
|
+
heNoNikud$1[key] = [Locale.hebrewStripNikkud(val[0])];
|
|
1114
|
+
}
|
|
1115
|
+
const poHeNoNikud$1 = {
|
|
1116
|
+
headers: poHe$1.headers,
|
|
1117
|
+
contexts: { '': heNoNikud$1 },
|
|
1118
|
+
};
|
|
1119
|
+
Locale.addLocale('he-x-NoNikud', poHeNoNikud$1);
|
|
1120
|
+
|
|
1121
|
+
/*! @hebcal/hdate v0.14.2, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
|
|
1122
|
+
|
|
1123
|
+
/*
|
|
1124
|
+
Hebcal - A Jewish Calendar Generator
|
|
1125
|
+
Copyright (c) 1994-2020 Danny Sadinoff
|
|
1126
|
+
Portions copyright Eyal Schachter and Michael J. Radwin
|
|
1127
|
+
|
|
1128
|
+
https://github.com/hebcal/hebcal-es6
|
|
1129
|
+
|
|
1130
|
+
This program is free software; you can redistribute it and/or
|
|
1131
|
+
modify it under the terms of the GNU General Public License
|
|
1132
|
+
as published by the Free Software Foundation; either version 2
|
|
1133
|
+
of the License, or (at your option) any later version.
|
|
1134
|
+
|
|
1135
|
+
This program is distributed in the hope that it will be useful,
|
|
1136
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
1137
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
1138
|
+
GNU General Public License for more details.
|
|
1139
|
+
|
|
1140
|
+
You should have received a copy of the GNU General Public License
|
|
1141
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
1142
|
+
*/
|
|
1143
|
+
function mod(x, y) {
|
|
1144
|
+
return x - y * Math.floor(x / y);
|
|
1145
|
+
}
|
|
1146
|
+
function isSimpleHebrewDate(obj) {
|
|
1147
|
+
return obj.yy !== undefined;
|
|
1148
|
+
}
|
|
1149
|
+
const UNITS_DAY = 'day';
|
|
1150
|
+
const UNITS_WEEK = 'week';
|
|
1151
|
+
const UNITS_MONTH = 'month';
|
|
1152
|
+
const UNITS_YEAR = 'year';
|
|
1153
|
+
/**
|
|
1154
|
+
* A `HDate` represents a Hebrew calendar date.
|
|
1155
|
+
*
|
|
1156
|
+
* An instance of this class encapsulates a date in the Hebrew calendar system.
|
|
1157
|
+
* It consists of a year, month, and day, without any associated time or location data.
|
|
1158
|
+
* The Hebrew calendar is a lunisolar calendar, meaning it is based on both lunar and solar cycles.
|
|
1159
|
+
*
|
|
1160
|
+
* A Hebrew date internally stores three numbers:
|
|
1161
|
+
* - year: The Hebrew year (1-9999). Counted from the traditional Hebrew date of creation (3761 BCE in the Gregorian calendar)
|
|
1162
|
+
* - 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.
|
|
1163
|
+
* - day: The day of the month (1-30)
|
|
1164
|
+
*
|
|
1165
|
+
* This class uses Rata Die to convert between the Hebrew and Gregorian calendars.
|
|
1166
|
+
*
|
|
1167
|
+
* To calculate times of day, use `Zmanim` class from `@hebcal/core`
|
|
1168
|
+
* @see {@link https://en.wikipedia.org/wiki/Rata_Die | Rata Die}
|
|
1169
|
+
* @see {@link https://hebcal.github.io/api/core/classes/Zmanim.html | Zmanim}
|
|
1170
|
+
*/
|
|
1171
|
+
class HDate {
|
|
1172
|
+
/**
|
|
1173
|
+
* Create a Hebrew date. There are 3 basic forms for the `HDate()` constructor.
|
|
1174
|
+
*
|
|
1175
|
+
* 1. No parameters - represents the current Hebrew date at time of instantiation
|
|
1176
|
+
* 2. One parameter
|
|
1177
|
+
* * `Date` - represents the Hebrew date corresponding to the Gregorian date using
|
|
1178
|
+
* local time. Hours, minutes, seconds and milliseconds are ignored.
|
|
1179
|
+
* * `HDate` - clones a copy of the given Hebrew date
|
|
1180
|
+
* * `number` - Converts absolute R.D. days to Hebrew date.
|
|
1181
|
+
* R.D. 1 == the imaginary date January 1, 1 (Gregorian)
|
|
1182
|
+
* 3. Three parameters: Hebrew day, Hebrew month, Hebrew year. Hebrew day should
|
|
1183
|
+
* be a number between 1-30, Hebrew month can be a number or string, and
|
|
1184
|
+
* Hebrew year is always a number.
|
|
1185
|
+
* @example
|
|
1186
|
+
* import {HDate, months} from '@hebcal/hdate';
|
|
1187
|
+
*
|
|
1188
|
+
* const hd1 = new HDate();
|
|
1189
|
+
* const hd2 = new HDate(new Date(2008, 10, 13));
|
|
1190
|
+
* const hd3 = new HDate(15, 'Cheshvan', 5769);
|
|
1191
|
+
* const hd4 = new HDate(15, months.CHESHVAN, 5769);
|
|
1192
|
+
* const hd5 = new HDate(733359); // ==> 15 Cheshvan 5769
|
|
1193
|
+
* const monthName = 'אייר';
|
|
1194
|
+
* const hd6 = new HDate(5, monthName, 5773);
|
|
1195
|
+
* @param [day] - Day of month (1-30) if a `number`.
|
|
1196
|
+
* If a `Date` is specified, represents the Hebrew date corresponding to the
|
|
1197
|
+
* Gregorian date using local time.
|
|
1198
|
+
* If an `HDate` is specified, clones a copy of the given Hebrew date.
|
|
1199
|
+
* @param [month] - Hebrew month of year (1=NISAN, 7=TISHREI)
|
|
1200
|
+
* @param [year] - Hebrew year
|
|
1201
|
+
*/
|
|
1202
|
+
constructor(day, month, year) {
|
|
1203
|
+
if (arguments.length === 2 || arguments.length > 3) {
|
|
1204
|
+
throw new TypeError('HDate constructor requires 0, 1 or 3 arguments');
|
|
1205
|
+
}
|
|
1206
|
+
if (arguments.length === 3) {
|
|
1207
|
+
// Hebrew day, Hebrew month, Hebrew year
|
|
1208
|
+
this.dd = this.mm = 1;
|
|
1209
|
+
const yy = typeof year === 'string' ? parseInt(year, 10) : year;
|
|
1210
|
+
if (isNaN(yy)) {
|
|
1211
|
+
throw new TypeError(`HDate called with bad year: ${year}`);
|
|
1212
|
+
}
|
|
1213
|
+
this.yy = yy;
|
|
1214
|
+
setMonth(this, month); // will throw if we can't parse
|
|
1215
|
+
const dd = typeof day === 'string' ? parseInt(day, 10) : day;
|
|
1216
|
+
if (isNaN(dd)) {
|
|
1217
|
+
throw new TypeError(`HDate called with bad day: ${day}`);
|
|
1218
|
+
}
|
|
1219
|
+
setDate(this, dd);
|
|
1220
|
+
}
|
|
1221
|
+
else {
|
|
1222
|
+
// 0 arguments
|
|
1223
|
+
if (typeof day === 'undefined' || day === null) {
|
|
1224
|
+
day = new Date();
|
|
1225
|
+
}
|
|
1226
|
+
// 1 argument
|
|
1227
|
+
const abs0 = typeof day === 'number' && !isNaN(day)
|
|
1228
|
+
? day
|
|
1229
|
+
: isDate(day)
|
|
1230
|
+
? greg2abs(day)
|
|
1231
|
+
: isSimpleHebrewDate(day)
|
|
1232
|
+
? day
|
|
1233
|
+
: null;
|
|
1234
|
+
if (abs0 === null) {
|
|
1235
|
+
throw new TypeError(`HDate called with bad arg: ${day}`);
|
|
1236
|
+
}
|
|
1237
|
+
const isNumber = typeof abs0 === 'number';
|
|
1238
|
+
const d = isNumber ? abs2hebrew(abs0) : abs0;
|
|
1239
|
+
this.yy = d.yy;
|
|
1240
|
+
this.mm = d.mm;
|
|
1241
|
+
this.dd = d.dd;
|
|
1242
|
+
if (isNumber) {
|
|
1243
|
+
this.rd = abs0;
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
/**
|
|
1248
|
+
* Returns the Hebrew year of this Hebrew date
|
|
1249
|
+
* @returns an integer >= 1
|
|
1250
|
+
* @example
|
|
1251
|
+
* const hd = new HDate(new Date(2008, 10, 13)); // 15 Cheshvan 5769
|
|
1252
|
+
* hd.getFullYear(); // 5769
|
|
1253
|
+
*/
|
|
1254
|
+
getFullYear() {
|
|
1255
|
+
return this.yy;
|
|
1256
|
+
}
|
|
1257
|
+
/**
|
|
1258
|
+
* Returns `true` if this Hebrew date occurs during a Hebrew leap year
|
|
1259
|
+
* @example
|
|
1260
|
+
* const hd = new HDate(new Date(2008, 10, 13)); // 15 Cheshvan 5769
|
|
1261
|
+
* hd.isLeapYear(); // false
|
|
1262
|
+
*/
|
|
1263
|
+
isLeapYear() {
|
|
1264
|
+
return isLeapYear(this.yy);
|
|
1265
|
+
}
|
|
1266
|
+
/**
|
|
1267
|
+
* Returns the Hebrew month (1=NISAN, 7=TISHREI) of this Hebrew date
|
|
1268
|
+
* @returns an integer 1-13
|
|
1269
|
+
* @example
|
|
1270
|
+
* const hd = new HDate(new Date(2008, 10, 13)); // 15 Cheshvan 5769
|
|
1271
|
+
* hd.getMonth(); // 8
|
|
1272
|
+
*/
|
|
1273
|
+
getMonth() {
|
|
1274
|
+
return this.mm;
|
|
1275
|
+
}
|
|
1276
|
+
/**
|
|
1277
|
+
* The Tishrei-based month of this Hebrew date. 1 is Tishrei, 7 is Nisan, 13 is Elul in a leap year
|
|
1278
|
+
* @returns an integer 1-13
|
|
1279
|
+
* @example
|
|
1280
|
+
* const hd = new HDate(new Date(2008, 10, 13)); // 15 Cheshvan 5769
|
|
1281
|
+
* hd.getTishreiMonth(); // 2
|
|
1282
|
+
*/
|
|
1283
|
+
getTishreiMonth() {
|
|
1284
|
+
const nummonths = monthsInYear(this.getFullYear());
|
|
1285
|
+
return (this.getMonth() + nummonths - 6) % nummonths || nummonths;
|
|
1286
|
+
}
|
|
1287
|
+
/**
|
|
1288
|
+
* Number of days in the month of this Hebrew date (29 or 30)
|
|
1289
|
+
* @returns an integer 29-30
|
|
1290
|
+
* @example
|
|
1291
|
+
* const hd = new HDate(new Date(2008, 10, 13)); // 15 Cheshvan 5769
|
|
1292
|
+
* hd.daysInMonth(); // 29
|
|
1293
|
+
*/
|
|
1294
|
+
daysInMonth() {
|
|
1295
|
+
return daysInMonth(this.getMonth(), this.getFullYear());
|
|
1296
|
+
}
|
|
1297
|
+
/**
|
|
1298
|
+
* Gets the day within the month (1-30)
|
|
1299
|
+
* @returns an integer 1-30
|
|
1300
|
+
* @example
|
|
1301
|
+
* const hd = new HDate(new Date(2008, 10, 13)); // 15 Cheshvan 5769
|
|
1302
|
+
* hd.getDate(); // 15
|
|
1303
|
+
*/
|
|
1304
|
+
getDate() {
|
|
1305
|
+
return this.dd;
|
|
1306
|
+
}
|
|
1307
|
+
/**
|
|
1308
|
+
* Returns the day of the week for this Hebrew date,
|
|
1309
|
+
* where 0 represents Sunday, 1 represents Monday, 6 represents Saturday.
|
|
1310
|
+
*
|
|
1311
|
+
* For the day of the month, see `getDate()`
|
|
1312
|
+
* @returns an integer 0-6
|
|
1313
|
+
* @example
|
|
1314
|
+
* const hd = new HDate(new Date(2008, 10, 13)); // 15 Cheshvan 5769
|
|
1315
|
+
* hd.getDate(); // 4
|
|
1316
|
+
*/
|
|
1317
|
+
getDay() {
|
|
1318
|
+
return mod(this.abs(), 7);
|
|
1319
|
+
}
|
|
1320
|
+
/**
|
|
1321
|
+
* Converts this Hebrew date to the corresponding Gregorian date.
|
|
1322
|
+
*
|
|
1323
|
+
* The returned `Date` object will be in the local (i.e. host system) time zone.
|
|
1324
|
+
* Hours, minutes, seconds and milliseconds will all be zero.
|
|
1325
|
+
*
|
|
1326
|
+
* Note that this function returns the daytime portion of the date.
|
|
1327
|
+
* For example, the 15th of Cheshvan 5769 began at sundown on
|
|
1328
|
+
* 12 November 2008 and continues through 13 November 2008. This
|
|
1329
|
+
* function would return only the date 13 November 2008.
|
|
1330
|
+
* @example
|
|
1331
|
+
* const hd = new HDate(15, 'Cheshvan', 5769);
|
|
1332
|
+
* const date = hd.greg(); // 13 November 2008
|
|
1333
|
+
* const year = date.getFullYear(); // 2008
|
|
1334
|
+
* const monthNum = date.getMonth() + 1; // 11
|
|
1335
|
+
* const day = date.getDate(); // 13
|
|
1336
|
+
*/
|
|
1337
|
+
greg() {
|
|
1338
|
+
return abs2greg(this.abs());
|
|
1339
|
+
}
|
|
1340
|
+
/**
|
|
1341
|
+
* Converts from Hebrew date representation to R.D. (Rata Die) fixed days.
|
|
1342
|
+
* R.D. 1 is the imaginary date Monday, January 1, 1 (Gregorian).
|
|
1343
|
+
* Note also that R.D. = Julian Date − 1,721,424.5
|
|
1344
|
+
* @see {@link https://en.wikipedia.org/wiki/Rata_Die | Rata Die}
|
|
1345
|
+
* @example
|
|
1346
|
+
* const hd = new HDate(15, 'Cheshvan', 5769);
|
|
1347
|
+
* hd.abs(); // 733359
|
|
1348
|
+
*/
|
|
1349
|
+
abs() {
|
|
1350
|
+
if (typeof this.rd !== 'number') {
|
|
1351
|
+
this.rd = hebrew2abs(this.yy, this.mm, this.dd);
|
|
1352
|
+
}
|
|
1353
|
+
return this.rd;
|
|
1354
|
+
}
|
|
1355
|
+
/**
|
|
1356
|
+
* Converts Hebrew date to R.D. (Rata Die) fixed days.
|
|
1357
|
+
* R.D. 1 is the imaginary date Monday, January 1, 1 on the Gregorian
|
|
1358
|
+
* Calendar.
|
|
1359
|
+
* @param year Hebrew year
|
|
1360
|
+
* @param month Hebrew month (1=NISAN, 7=TISHREI)
|
|
1361
|
+
* @param day Hebrew date (1-30)
|
|
1362
|
+
* @example
|
|
1363
|
+
* import {HDate, months} from '@hebcal/hdate';
|
|
1364
|
+
* HDate.hebrew2abs(5769, months.CHESHVAN, 15); // 733359
|
|
1365
|
+
*/
|
|
1366
|
+
static hebrew2abs(year, month, day) {
|
|
1367
|
+
return hebrew2abs(year, month, day);
|
|
1368
|
+
}
|
|
1369
|
+
/**
|
|
1370
|
+
* Returns a transliterated Hebrew month name, e.g. `'Elul'` or `'Cheshvan'`.
|
|
1371
|
+
* @example
|
|
1372
|
+
* const hd = new HDate(new Date(2008, 10, 13)); // 15 Cheshvan 5769
|
|
1373
|
+
* hd.getMonthName(); // 'Cheshvan'
|
|
1374
|
+
*/
|
|
1375
|
+
getMonthName() {
|
|
1376
|
+
return getMonthName(this.getMonth(), this.getFullYear());
|
|
1377
|
+
}
|
|
1378
|
+
/**
|
|
1379
|
+
* Renders this Hebrew date as a translated or transliterated string,
|
|
1380
|
+
* including ordinal e.g. `'15th of Cheshvan, 5769'`.
|
|
1381
|
+
* @example
|
|
1382
|
+
* import {HDate, months} from '@hebcal/hdate';
|
|
1383
|
+
*
|
|
1384
|
+
* const hd = new HDate(15, months.CHESHVAN, 5769);
|
|
1385
|
+
* console.log(hd.render('en')); // '15th of Cheshvan, 5769'
|
|
1386
|
+
* console.log(hd.render('he')); // '15 חֶשְׁוָן, 5769'
|
|
1387
|
+
* console.log(hd.render('en', false)); // '15th of Cheshvan'
|
|
1388
|
+
* console.log(hd.render('he', false)); // '15 חֶשְׁוָן'
|
|
1389
|
+
* @param [locale] Optional locale name (defaults to active locale).
|
|
1390
|
+
* @param [showYear=true] Display year (defaults to true).
|
|
1391
|
+
* @see {@link Locale}
|
|
1392
|
+
*/
|
|
1393
|
+
render(locale, showYear = true) {
|
|
1394
|
+
const locale0 = locale || Locale.getLocaleName();
|
|
1395
|
+
const day = this.getDate();
|
|
1396
|
+
const monthName0 = Locale.gettext(this.getMonthName(), locale0);
|
|
1397
|
+
const monthName = monthName0.replace(/'/g, '’');
|
|
1398
|
+
const nth = Locale.ordinal(day, locale0);
|
|
1399
|
+
const dayOf = getDayOfTranslation(locale0);
|
|
1400
|
+
const dateStr = `${nth}${dayOf} ${monthName}`;
|
|
1401
|
+
if (showYear) {
|
|
1402
|
+
const fullYear = this.getFullYear();
|
|
1403
|
+
return `${dateStr}, ${fullYear}`;
|
|
1404
|
+
}
|
|
1405
|
+
else {
|
|
1406
|
+
return dateStr;
|
|
1407
|
+
}
|
|
1408
|
+
}
|
|
1409
|
+
/**
|
|
1410
|
+
* Renders this Hebrew date in Hebrew gematriya, regardless of locale.
|
|
1411
|
+
* @example
|
|
1412
|
+
* import {HDate, months} from '@hebcal/hdate';
|
|
1413
|
+
* const hd = new HDate(15, months.CHESHVAN, 5769);
|
|
1414
|
+
* hd.renderGematriya(); // 'ט״ו חֶשְׁוָן תשס״ט'
|
|
1415
|
+
* hd.renderGematriya(true); // 'ט״ו חשון תשס״ט'
|
|
1416
|
+
*/
|
|
1417
|
+
renderGematriya(suppressNikud = false) {
|
|
1418
|
+
const d = this.getDate();
|
|
1419
|
+
const locale = suppressNikud ? 'he-x-NoNikud' : 'he';
|
|
1420
|
+
const m = Locale.gettext(this.getMonthName(), locale);
|
|
1421
|
+
const y = this.getFullYear();
|
|
1422
|
+
return gematriya(d) + ' ' + m + ' ' + gematriya(y);
|
|
1423
|
+
}
|
|
1424
|
+
/**
|
|
1425
|
+
* Returns an `HDate` corresponding to the specified day of week
|
|
1426
|
+
* **before** this Hebrew date
|
|
1427
|
+
* @example
|
|
1428
|
+
* new HDate(new Date('Wednesday February 19, 2014')).before(6).greg() // Sat Feb 15 2014
|
|
1429
|
+
* @param dayOfWeek day of week: Sunday=0, Saturday=6
|
|
1430
|
+
*/
|
|
1431
|
+
before(dayOfWeek) {
|
|
1432
|
+
return onOrBefore(dayOfWeek, this, -1);
|
|
1433
|
+
}
|
|
1434
|
+
/**
|
|
1435
|
+
* Returns an `HDate` corresponding to the specified day of week
|
|
1436
|
+
* **on or before** this Hebrew date
|
|
1437
|
+
* @example
|
|
1438
|
+
* new HDate(new Date('Wednesday February 19, 2014')).onOrBefore(6).greg() // Sat Feb 15 2014
|
|
1439
|
+
* new HDate(new Date('Saturday February 22, 2014')).onOrBefore(6).greg() // Sat Feb 22 2014
|
|
1440
|
+
* new HDate(new Date('Sunday February 23, 2014')).onOrBefore(6).greg() // Sat Feb 22 2014
|
|
1441
|
+
* @param dayOfWeek day of week: Sunday=0, Saturday=6
|
|
1442
|
+
*/
|
|
1443
|
+
onOrBefore(dayOfWeek) {
|
|
1444
|
+
return onOrBefore(dayOfWeek, this, 0);
|
|
1445
|
+
}
|
|
1446
|
+
/**
|
|
1447
|
+
* Returns an `HDate` corresponding to the specified day of week
|
|
1448
|
+
* **nearest** to this Hebrew date
|
|
1449
|
+
* @example
|
|
1450
|
+
* new HDate(new Date('Wednesday February 19, 2014')).nearest(6).greg() // Sat Feb 22 2014
|
|
1451
|
+
* new HDate(new Date('Tuesday February 18, 2014')).nearest(6).greg() // Sat Feb 15 2014
|
|
1452
|
+
* @param dayOfWeek day of week: Sunday=0, Saturday=6
|
|
1453
|
+
*/
|
|
1454
|
+
nearest(dayOfWeek) {
|
|
1455
|
+
return onOrBefore(dayOfWeek, this, 3);
|
|
1456
|
+
}
|
|
1457
|
+
/**
|
|
1458
|
+
* Returns an `HDate` corresponding to the specified day of week
|
|
1459
|
+
* **on or after** this Hebrew date
|
|
1460
|
+
* @example
|
|
1461
|
+
* new HDate(new Date('Wednesday February 19, 2014')).onOrAfter(6).greg() // Sat Feb 22 2014
|
|
1462
|
+
* new HDate(new Date('Saturday February 22, 2014')).onOrAfter(6).greg() // Sat Feb 22 2014
|
|
1463
|
+
* new HDate(new Date('Sunday February 23, 2014')).onOrAfter(6).greg() // Sat Mar 01 2014
|
|
1464
|
+
* @param dayOfWeek day of week: Sunday=0, Saturday=6
|
|
1465
|
+
*/
|
|
1466
|
+
onOrAfter(dayOfWeek) {
|
|
1467
|
+
return onOrBefore(dayOfWeek, this, 6);
|
|
1468
|
+
}
|
|
1469
|
+
/**
|
|
1470
|
+
* Returns an `HDate` corresponding to the specified day of week
|
|
1471
|
+
* **after** this Hebrew date
|
|
1472
|
+
* @example
|
|
1473
|
+
* new HDate(new Date('Wednesday February 19, 2014')).after(6).greg() // Sat Feb 22 2014
|
|
1474
|
+
* new HDate(new Date('Saturday February 22, 2014')).after(6).greg() // Sat Mar 01 2014
|
|
1475
|
+
* new HDate(new Date('Sunday February 23, 2014')).after(6).greg() // Sat Mar 01 2014
|
|
1476
|
+
* @param dayOfWeek day of week: Sunday=0, Saturday=6
|
|
1477
|
+
*/
|
|
1478
|
+
after(dayOfWeek) {
|
|
1479
|
+
return onOrBefore(dayOfWeek, this, 7);
|
|
1480
|
+
}
|
|
1481
|
+
/**
|
|
1482
|
+
* Returns the next Hebrew date
|
|
1483
|
+
* @example
|
|
1484
|
+
* const hd = new HDate(new Date(2008, 10, 13)); // 15 Cheshvan 5769
|
|
1485
|
+
* hd.next(); // '16 Cheshvan 5769'
|
|
1486
|
+
*/
|
|
1487
|
+
next() {
|
|
1488
|
+
return new HDate(this.abs() + 1);
|
|
1489
|
+
}
|
|
1490
|
+
/**
|
|
1491
|
+
* Returns the previous Hebrew date
|
|
1492
|
+
* @example
|
|
1493
|
+
* const hd = new HDate(new Date(2008, 10, 13)); // 15 Cheshvan 5769
|
|
1494
|
+
* hd.prev(); // '14 Cheshvan 5769'
|
|
1495
|
+
*/
|
|
1496
|
+
prev() {
|
|
1497
|
+
return new HDate(this.abs() - 1);
|
|
1498
|
+
}
|
|
1499
|
+
/**
|
|
1500
|
+
* Returns a cloned `HDate` object with a specified amount of time added
|
|
1501
|
+
*
|
|
1502
|
+
* Units are case insensitive, and support plural and short forms.
|
|
1503
|
+
* Note, short forms are case sensitive.
|
|
1504
|
+
*
|
|
1505
|
+
* | Unit | Shorthand | Description
|
|
1506
|
+
* | --- | --- | --- |
|
|
1507
|
+
* | `day` | `d` | days |
|
|
1508
|
+
* | `week` | `w` | weeks |
|
|
1509
|
+
* | `month` | `M` | months |
|
|
1510
|
+
* | `year` | `y` | years |
|
|
1511
|
+
*/
|
|
1512
|
+
add(amount, units = 'd') {
|
|
1513
|
+
amount =
|
|
1514
|
+
typeof amount === 'string' ? parseInt(amount, 10) : amount;
|
|
1515
|
+
if (!amount) {
|
|
1516
|
+
return new HDate(this);
|
|
1517
|
+
}
|
|
1518
|
+
units = standardizeUnits(units);
|
|
1519
|
+
if (units === UNITS_DAY) {
|
|
1520
|
+
return new HDate(this.abs() + amount);
|
|
1521
|
+
}
|
|
1522
|
+
else if (units === UNITS_WEEK) {
|
|
1523
|
+
return new HDate(this.abs() + 7 * amount);
|
|
1524
|
+
}
|
|
1525
|
+
else if (units === UNITS_YEAR) {
|
|
1526
|
+
return new HDate(this.getDate(), this.getMonth(), this.getFullYear() + amount);
|
|
1527
|
+
}
|
|
1528
|
+
else {
|
|
1529
|
+
// units === UNITS_MONTH
|
|
1530
|
+
let hd = new HDate(this);
|
|
1531
|
+
const sign = amount > 0 ? 1 : -1;
|
|
1532
|
+
amount = Math.abs(amount);
|
|
1533
|
+
for (let i = 0; i < amount; i++) {
|
|
1534
|
+
hd = new HDate(hd.abs() + sign * hd.daysInMonth());
|
|
1535
|
+
}
|
|
1536
|
+
return hd;
|
|
1537
|
+
}
|
|
1538
|
+
}
|
|
1539
|
+
/**
|
|
1540
|
+
* Returns a cloned `HDate` object with a specified amount of time subracted
|
|
1541
|
+
*
|
|
1542
|
+
* Units are case insensitive, and support plural and short forms.
|
|
1543
|
+
* Note, short forms are case sensitive.
|
|
1544
|
+
*
|
|
1545
|
+
* | Unit | Shorthand | Description
|
|
1546
|
+
* | --- | --- | --- |
|
|
1547
|
+
* | `day` | `d` | days |
|
|
1548
|
+
* | `week` | `w` | weeks |
|
|
1549
|
+
* | `month` | `M` | months |
|
|
1550
|
+
* | `year` | `y` | years |
|
|
1551
|
+
* @example
|
|
1552
|
+
* import {HDate, months} from '@hebcal/hdate';
|
|
1553
|
+
*
|
|
1554
|
+
* const hd1 = new HDate(15, months.CHESHVAN, 5769);
|
|
1555
|
+
* const hd2 = hd1.add(1, 'weeks'); // 7 Kislev 5769
|
|
1556
|
+
* const hd3 = hd1.add(-3, 'M'); // 30 Av 5768
|
|
1557
|
+
*/
|
|
1558
|
+
subtract(amount, units = 'd') {
|
|
1559
|
+
return this.add(amount * -1, units);
|
|
1560
|
+
}
|
|
1561
|
+
/**
|
|
1562
|
+
* Returns the difference in days between the two given HDates.
|
|
1563
|
+
*
|
|
1564
|
+
* The result is positive if `this` date is comes chronologically
|
|
1565
|
+
* after the `other` date, and negative
|
|
1566
|
+
* if the order of the two dates is reversed.
|
|
1567
|
+
*
|
|
1568
|
+
* The result is zero if the two dates are identical.
|
|
1569
|
+
* @example
|
|
1570
|
+
* import {HDate, months} from '@hebcal/hdate';
|
|
1571
|
+
*
|
|
1572
|
+
* const hd1 = new HDate(25, months.KISLEV, 5770);
|
|
1573
|
+
* const hd2 = new HDate(15, months.CHESHVAN, 5769);
|
|
1574
|
+
* const days = hd1.deltaDays(hd2); // 394
|
|
1575
|
+
* @param other Hebrew date to compare
|
|
1576
|
+
*/
|
|
1577
|
+
deltaDays(other) {
|
|
1578
|
+
return this.abs() - other.abs();
|
|
1579
|
+
}
|
|
1580
|
+
/**
|
|
1581
|
+
* Compares this Hebrew date to another date, returning `true` if the dates match.
|
|
1582
|
+
* @param other Hebrew date to compare
|
|
1583
|
+
* @example
|
|
1584
|
+
* const hd1 = new HDate(new Date(2008, 10, 13));
|
|
1585
|
+
* const hd2 = new HDate(15, 'Cheshvan', 5769);
|
|
1586
|
+
* hd1.isSameDate(hd2); // true
|
|
1587
|
+
*/
|
|
1588
|
+
isSameDate(other) {
|
|
1589
|
+
return this.yy === other.yy && this.mm === other.mm && this.dd === other.dd;
|
|
1590
|
+
}
|
|
1591
|
+
/**
|
|
1592
|
+
* Returns a string representation of this Hebrew date using English transliterations
|
|
1593
|
+
* @example
|
|
1594
|
+
* const hd = new HDate(new Date(2008, 10, 13)); // 15 Cheshvan 5769
|
|
1595
|
+
* hd.toString(); // '15 Cheshvan 5769'
|
|
1596
|
+
*/
|
|
1597
|
+
toString() {
|
|
1598
|
+
const day = this.getDate();
|
|
1599
|
+
const fullYear = this.getFullYear();
|
|
1600
|
+
const monthName = this.getMonthName();
|
|
1601
|
+
return `${day} ${monthName} ${fullYear}`;
|
|
1602
|
+
}
|
|
1603
|
+
/**
|
|
1604
|
+
* Returns true if Hebrew year is a leap year
|
|
1605
|
+
* @param year Hebrew year
|
|
1606
|
+
* @example
|
|
1607
|
+
* HDate.isLeapYear(5783); // false
|
|
1608
|
+
* HDate.isLeapYear(5784); // true
|
|
1609
|
+
*/
|
|
1610
|
+
static isLeapYear(year) {
|
|
1611
|
+
return isLeapYear(year);
|
|
1612
|
+
}
|
|
1613
|
+
/**
|
|
1614
|
+
* Number of months in this Hebrew year (either 12 or 13 depending on leap year)
|
|
1615
|
+
* @param year Hebrew year
|
|
1616
|
+
* @example
|
|
1617
|
+
* HDate.monthsInYear(5783); // 12
|
|
1618
|
+
* HDate.monthsInYear(5784); // 13
|
|
1619
|
+
*/
|
|
1620
|
+
static monthsInYear(year) {
|
|
1621
|
+
return monthsInYear(year);
|
|
1622
|
+
}
|
|
1623
|
+
/**
|
|
1624
|
+
* Number of days in Hebrew month in a given year (29 or 30)
|
|
1625
|
+
* @param month Hebrew month (e.g. months.TISHREI)
|
|
1626
|
+
* @param year Hebrew year
|
|
1627
|
+
* @example
|
|
1628
|
+
* import {HDate, months} from '@hebcal/hdate';
|
|
1629
|
+
* HDate.daysInMonth(months.CHESHVAN, 5769); // 29
|
|
1630
|
+
*/
|
|
1631
|
+
static daysInMonth(month, year) {
|
|
1632
|
+
return daysInMonth(month, year);
|
|
1633
|
+
}
|
|
1634
|
+
/**
|
|
1635
|
+
* Returns a transliterated string name of Hebrew month in year,
|
|
1636
|
+
* for example 'Elul' or 'Cheshvan'.
|
|
1637
|
+
* @param month Hebrew month (e.g. months.TISHREI)
|
|
1638
|
+
* @param year Hebrew year
|
|
1639
|
+
* @example
|
|
1640
|
+
* import {HDate, months} from '@hebcal/hdate';
|
|
1641
|
+
* HDate.getMonthName(months.CHESHVAN, 5769); // 'Cheshvan'
|
|
1642
|
+
*/
|
|
1643
|
+
static getMonthName(month, year) {
|
|
1644
|
+
return getMonthName(month, year);
|
|
1645
|
+
}
|
|
1646
|
+
/**
|
|
1647
|
+
* Returns the Hebrew month number (NISAN=1, TISHREI=7)
|
|
1648
|
+
* @param month A number, or Hebrew month name string
|
|
1649
|
+
* @example
|
|
1650
|
+
* import {HDate, months} from '@hebcal/hdate';
|
|
1651
|
+
* HDate.monthNum(months.CHESHVAN); // 8
|
|
1652
|
+
* HDate.monthNum('Cheshvan'); // 8
|
|
1653
|
+
* HDate.monthNum('חשון'); // 8
|
|
1654
|
+
*/
|
|
1655
|
+
static monthNum(month) {
|
|
1656
|
+
if (typeof month === 'number') {
|
|
1657
|
+
if (isNaN(month) || month > 14) {
|
|
1658
|
+
throw new RangeError(`bad monthNum: ${month}`);
|
|
1659
|
+
}
|
|
1660
|
+
return month;
|
|
1661
|
+
}
|
|
1662
|
+
return month.charCodeAt(0) >= 48 && month.charCodeAt(0) <= 57 /* number */
|
|
1663
|
+
? parseInt(month, 10)
|
|
1664
|
+
: HDate.monthFromName(month);
|
|
1665
|
+
}
|
|
1666
|
+
/**
|
|
1667
|
+
* Number of days in the Hebrew year.
|
|
1668
|
+
* Regular years can have 353, 354, or 355 days.
|
|
1669
|
+
* Leap years can have 383, 384, or 385 days.
|
|
1670
|
+
* @param year Hebrew year
|
|
1671
|
+
* @example
|
|
1672
|
+
* HDate.daysInYear(5783); // 355
|
|
1673
|
+
* HDate.daysInYear(5784); // 383
|
|
1674
|
+
*/
|
|
1675
|
+
static daysInYear(year) {
|
|
1676
|
+
return daysInYear(year);
|
|
1677
|
+
}
|
|
1678
|
+
/**
|
|
1679
|
+
* true if Cheshvan is long in Hebrew year
|
|
1680
|
+
* @param year Hebrew year
|
|
1681
|
+
* @example
|
|
1682
|
+
* HDate.longCheshvan(5783); // true
|
|
1683
|
+
* HDate.longCheshvan(5784); // false
|
|
1684
|
+
*/
|
|
1685
|
+
static longCheshvan(year) {
|
|
1686
|
+
return longCheshvan(year);
|
|
1687
|
+
}
|
|
1688
|
+
/**
|
|
1689
|
+
* true if Kislev is short in Hebrew year
|
|
1690
|
+
* @param year Hebrew year
|
|
1691
|
+
* @example
|
|
1692
|
+
* HDate.shortKislev(5783); // false
|
|
1693
|
+
* HDate.shortKislev(5784); // true
|
|
1694
|
+
*/
|
|
1695
|
+
static shortKislev(year) {
|
|
1696
|
+
return shortKislev(year);
|
|
1697
|
+
}
|
|
1698
|
+
/**
|
|
1699
|
+
* Converts Hebrew month string name to numeric
|
|
1700
|
+
* @example
|
|
1701
|
+
* import {HDate, months} from '@hebcal/hdate';
|
|
1702
|
+
* HDate.monthFromName(months.CHESHVAN); // 8
|
|
1703
|
+
* HDate.monthFromName('Cheshvan'); // 8
|
|
1704
|
+
* HDate.monthFromName('חשון'); // 8
|
|
1705
|
+
*/
|
|
1706
|
+
static monthFromName(monthName) {
|
|
1707
|
+
if (typeof monthName === 'number') {
|
|
1708
|
+
if (isNaN(monthName) || monthName < 1 || monthName > 14) {
|
|
1709
|
+
throw new RangeError(`bad monthName: ${monthName}`);
|
|
1710
|
+
}
|
|
1711
|
+
return monthName;
|
|
1712
|
+
}
|
|
1713
|
+
const name = Locale.hebrewStripNikkud(monthName);
|
|
1714
|
+
return monthFromName(name);
|
|
1715
|
+
}
|
|
1716
|
+
/**
|
|
1717
|
+
* Convenience function for determining the R.D. date
|
|
1718
|
+
* near a specified R.D. date, corresponding to the specified day of week.
|
|
1719
|
+
*
|
|
1720
|
+
* Note: Applying this function to d+6 gives us the `dayOfWeek` on or after an
|
|
1721
|
+
* absolute day d. Similarly, applying it to d+3 gives the `dayOfWeek` nearest to
|
|
1722
|
+
* absolute date d, applying it to d-1 gives the `dayOfWeek` previous to absolute
|
|
1723
|
+
* date d, and applying it to d+7 gives the `dayOfWeek` following absolute date d.
|
|
1724
|
+
* @param dayOfWeek day of week: Sunday=0, Saturday=6
|
|
1725
|
+
*/
|
|
1726
|
+
static dayOnOrBefore(dayOfWeek, absdate) {
|
|
1727
|
+
return absdate - ((absdate - dayOfWeek) % 7);
|
|
1728
|
+
}
|
|
1729
|
+
/**
|
|
1730
|
+
* Tests if the object is an instance of `HDate`
|
|
1731
|
+
* @example
|
|
1732
|
+
* HDate.isHDate(new HDate()); // true
|
|
1733
|
+
* HDate.isHDate(new Date()); // false
|
|
1734
|
+
* HDate.isHDate(null); // false
|
|
1735
|
+
* HDate.isHDate(12345); // false
|
|
1736
|
+
* HDate.isHDate('15 Cheshvan 5769'); // false
|
|
1737
|
+
*/
|
|
1738
|
+
static isHDate(obj) {
|
|
1739
|
+
return (obj !== null &&
|
|
1740
|
+
typeof obj === 'object' &&
|
|
1741
|
+
typeof obj.yy === 'number' &&
|
|
1742
|
+
typeof obj.mm === 'number' &&
|
|
1743
|
+
typeof obj.dd === 'number' &&
|
|
1744
|
+
typeof obj.greg === 'function' &&
|
|
1745
|
+
typeof obj.abs === 'function');
|
|
1746
|
+
}
|
|
1747
|
+
/**
|
|
1748
|
+
* Construct a new instance of `HDate` from a Gematriya-formatted string
|
|
1749
|
+
* @example
|
|
1750
|
+
* HDate.fromGematriyaString('כ״ז בְּתַמּוּז תשפ״ג') // 27 Tamuz 5783
|
|
1751
|
+
* HDate.fromGematriyaString('כ׳ סיון תש״ד') // 20 Sivan 5704
|
|
1752
|
+
* HDate.fromGematriyaString('ה׳ אִיָיר תש״ח') // 5 Iyyar 5708
|
|
1753
|
+
*/
|
|
1754
|
+
static fromGematriyaString(str, currentThousands = 5000) {
|
|
1755
|
+
const parts = str.split(' ').filter(x => x.length !== 0);
|
|
1756
|
+
const numParts = parts.length;
|
|
1757
|
+
if (numParts !== 3 && numParts !== 4) {
|
|
1758
|
+
throw new RangeError(`cannot parse gematriya str: "${str}"`);
|
|
1759
|
+
}
|
|
1760
|
+
const day = gematriyaStrToNum(parts[0]);
|
|
1761
|
+
const monthStr = numParts === 3 ? parts[1] : parts[1] + ' ' + parts[2];
|
|
1762
|
+
const month = HDate.monthFromName(monthStr);
|
|
1763
|
+
const yearStr = numParts === 3 ? parts[2] : parts[3];
|
|
1764
|
+
let year = gematriyaStrToNum(yearStr);
|
|
1765
|
+
if (year < 1000) {
|
|
1766
|
+
year += currentThousands;
|
|
1767
|
+
}
|
|
1768
|
+
return new HDate(day, month, year);
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
function standardizeUnits(units) {
|
|
1772
|
+
switch (units) {
|
|
1773
|
+
case 'd':
|
|
1774
|
+
return UNITS_DAY;
|
|
1775
|
+
case 'w':
|
|
1776
|
+
return UNITS_WEEK;
|
|
1777
|
+
case 'M':
|
|
1778
|
+
return UNITS_MONTH;
|
|
1779
|
+
case 'y':
|
|
1780
|
+
return UNITS_YEAR;
|
|
1781
|
+
}
|
|
1782
|
+
const str = String(units || '')
|
|
1783
|
+
.toLowerCase()
|
|
1784
|
+
.replace(/s$/, '');
|
|
1785
|
+
switch (str) {
|
|
1786
|
+
case UNITS_DAY:
|
|
1787
|
+
case UNITS_WEEK:
|
|
1788
|
+
case UNITS_MONTH:
|
|
1789
|
+
case UNITS_YEAR:
|
|
1790
|
+
return str;
|
|
1791
|
+
}
|
|
1792
|
+
throw new TypeError(`Invalid units '${units}'`);
|
|
1793
|
+
}
|
|
1794
|
+
function getDayOfTranslation(locale) {
|
|
1795
|
+
switch (locale) {
|
|
1796
|
+
case 'en':
|
|
1797
|
+
case 's':
|
|
1798
|
+
case 'a':
|
|
1799
|
+
case 'ashkenazi':
|
|
1800
|
+
return ' of';
|
|
1801
|
+
}
|
|
1802
|
+
const ofStr = Locale.lookupTranslation('of', locale);
|
|
1803
|
+
if (ofStr) {
|
|
1804
|
+
return ' ' + ofStr;
|
|
1805
|
+
}
|
|
1806
|
+
if (locale.startsWith('ashkenazi')) {
|
|
1807
|
+
return ' of';
|
|
1808
|
+
}
|
|
1809
|
+
return '';
|
|
1810
|
+
}
|
|
1811
|
+
/**
|
|
1812
|
+
* Sets the day of the month of the date. Returns the object it was called upon
|
|
1813
|
+
* @private
|
|
1814
|
+
* @param month A number, or Hebrew month name string
|
|
1815
|
+
*/
|
|
1816
|
+
function setMonth(hd, month) {
|
|
1817
|
+
hd.mm = HDate.monthNum(month);
|
|
1818
|
+
fix(hd);
|
|
1819
|
+
return hd;
|
|
1820
|
+
}
|
|
1821
|
+
function setDate(hd, date) {
|
|
1822
|
+
hd.dd = date;
|
|
1823
|
+
fix(hd);
|
|
1824
|
+
return hd;
|
|
1825
|
+
}
|
|
1826
|
+
function fix(hd) {
|
|
1827
|
+
fixMonth(hd);
|
|
1828
|
+
fixDate(hd);
|
|
1829
|
+
}
|
|
1830
|
+
function fixDate(hd) {
|
|
1831
|
+
if (hd.dd < 1) {
|
|
1832
|
+
if (hd.mm === months.TISHREI) {
|
|
1833
|
+
hd.yy -= 1;
|
|
1834
|
+
}
|
|
1835
|
+
hd.dd += daysInMonth(hd.mm, hd.yy);
|
|
1836
|
+
hd.mm -= 1;
|
|
1837
|
+
fix(hd);
|
|
1838
|
+
}
|
|
1839
|
+
if (hd.dd > daysInMonth(hd.mm, hd.yy)) {
|
|
1840
|
+
if (hd.mm === months.ELUL) {
|
|
1841
|
+
hd.yy += 1;
|
|
1842
|
+
}
|
|
1843
|
+
hd.dd -= daysInMonth(hd.mm, hd.yy);
|
|
1844
|
+
if (hd.mm === monthsInYear(hd.yy)) {
|
|
1845
|
+
hd.mm = 1; // rollover to NISAN
|
|
1846
|
+
}
|
|
1847
|
+
else {
|
|
1848
|
+
hd.mm += 1;
|
|
1849
|
+
}
|
|
1850
|
+
fix(hd);
|
|
1851
|
+
}
|
|
1852
|
+
fixMonth(hd);
|
|
1853
|
+
}
|
|
1854
|
+
function fixMonth(hd) {
|
|
1855
|
+
if (hd.mm === months.ADAR_II && !hd.isLeapYear()) {
|
|
1856
|
+
hd.mm -= 1; // to Adar I
|
|
1857
|
+
fix(hd);
|
|
1858
|
+
}
|
|
1859
|
+
else if (hd.mm < 1) {
|
|
1860
|
+
hd.mm += monthsInYear(hd.yy);
|
|
1861
|
+
hd.yy -= 1;
|
|
1862
|
+
fix(hd);
|
|
1863
|
+
}
|
|
1864
|
+
else if (hd.mm > monthsInYear(hd.yy)) {
|
|
1865
|
+
hd.mm -= monthsInYear(hd.yy);
|
|
1866
|
+
hd.yy += 1;
|
|
1867
|
+
fix(hd);
|
|
1868
|
+
}
|
|
1869
|
+
delete hd.rd;
|
|
1870
|
+
}
|
|
1871
|
+
function onOrBefore(day, t, offset) {
|
|
1872
|
+
return new HDate(HDate.dayOnOrBefore(day, t.abs() + offset));
|
|
1873
|
+
}
|
|
10
1874
|
|
|
11
1875
|
var poAshkenazi = { "headers": { "plural-forms": "nplurals=2; plural=(n > 1);", "language": "en_CA@ashkenazi" }, "contexts": { "": { "Shabbat": ["Shabbos"], "Achrei Mot": ["Achrei Mos"], "Bechukotai": ["Bechukosai"], "Beha'alotcha": ["Beha’aloscha"], "Bereshit": ["Bereshis"], "Chukat": ["Chukas"], "Erev Shavuot": ["Erev Shavuos"], "Erev Sukkot": ["Erev Sukkos"], "Ki Tavo": ["Ki Savo"], "Ki Teitzei": ["Ki Seitzei"], "Ki Tisa": ["Ki Sisa"], "Matot": ["Matos"], "Purim Katan": ["Purim Koton"], "Shabbat Chazon": ["Shabbos Chazon"], "Shabbat HaChodesh": ["Shabbos HaChodesh"], "Shabbat HaGadol": ["Shabbos HaGadol"], "Shabbat Nachamu": ["Shabbos Nachamu"], "Shabbat Parah": ["Shabbos Parah"], "Shabbat Shekalim": ["Shabbos Shekalim"], "Shabbat Shuva": ["Shabbos Shuvah"], "Shabbat Zachor": ["Shabbos Zachor"], "Shavuot": ["Shavuos"], "Shavuot I": ["Shavuos I"], "Shavuot II": ["Shavuos II"], "Shemot": ["Shemos"], "Shmini Atzeret": ["Shmini Atzeres"], "Simchat Torah": ["Simchas Torah"], "Sukkot": ["Sukkos"], "Sukkot I": ["Sukkos I"], "Sukkot II": ["Sukkos II"], "Sukkot II (CH''M)": ["Sukkos II (CH’’M)"], "Sukkot III (CH''M)": ["Sukkos III (CH’’M)"], "Sukkot IV (CH''M)": ["Sukkos IV (CH’’M)"], "Sukkot V (CH''M)": ["Sukkos V (CH’’M)"], "Sukkot VI (CH''M)": ["Sukkos VI (CH’’M)"], "Sukkot VII (Hoshana Raba)": ["Sukkos VII (Hoshana Raba)"], "Ta'anit Bechorot": ["Ta’anis Bechoros"], "Ta'anit Esther": ["Ta’anis Esther"], "Toldot": ["Toldos"], "Vaetchanan": ["Vaeschanan"], "Yitro": ["Yisro"], "Vezot Haberakhah": ["Vezos Haberakhah"], "Parashat": ["Parshas"], "Leil Selichot": ["Leil Selichos"], "Shabbat Mevarchim Chodesh": ["Shabbos Mevorchim Chodesh"], "Shabbat Shirah": ["Shabbos Shirah"], "Asara B'Tevet": ["Asara B’Teves"], "Alot HaShachar": ["Alos HaShachar"], "Kriat Shema, sof zeman": ["Krias Shema, sof zman"], "Tefilah, sof zeman": ["Tefilah, sof zman"], "Kriat Shema, sof zeman (MGA)": ["Krias Shema, sof zman (MGA)"], "Tefilah, sof zeman (MGA)": ["Tefilah, sof zman (MGA)"], "Chatzot HaLailah": ["Chatzos HaLailah"], "Chatzot hayom": ["Chatzos"], "Tzeit HaKochavim": ["Tzeis HaKochavim"], "Birkat Hachamah": ["Birkas Hachamah"], "Shushan Purim Katan": ["Shushan Purim Koton"] } } };
|
|
12
1876
|
|
|
13
|
-
var poHe = { "headers": { "plural-forms": "nplurals=2; plural=(n > 1);", "language": "he_IL" }, "contexts": { "": { "Shabbat": ["שַׁבָּת"], "Daf Yomi": ["דַף יוֹמִי"], "Parashat": ["פָּרָשַׁת"], "Achrei Mot": ["אַחֲרֵי מוֹת"], "Balak": ["בָּלָק"], "Bamidbar": ["בְּמִדְבַּר"], "Bechukotai": ["בְּחֻקֹּתַי"], "Beha'alotcha": ["בְּהַעֲלֹתְךָ"], "Behar": ["בְּהַר"], "Bereshit": ["בְּרֵאשִׁית"], "Beshalach": ["בְּשַׁלַּח"], "Bo": ["בֹּא"], "Chayei Sara": ["חַיֵּי שָֹרָה"], "Chukat": ["חֻקַּת"], "Devarim": ["דְּבָרִים"], "Eikev": ["עֵקֶב"], "Emor": ["אֱמוֹר"], "Ha'azinu": ["הַאֲזִינוּ"], "Kedoshim": ["קְדשִׁים"], "Ki Tavo": ["כִּי־תָבוֹא"], "Ki Teitzei": ["כִּי־תֵצֵא"], "Ki Tisa": ["כִּי תִשָּׂא"], "Korach": ["
|
|
1877
|
+
var poHe = { "headers": { "plural-forms": "nplurals=2; plural=(n > 1);", "language": "he_IL" }, "contexts": { "": { "Shabbat": ["שַׁבָּת"], "Daf Yomi": ["דַף יוֹמִי"], "Parashat": ["פָּרָשַׁת"], "Achrei Mot": ["אַחֲרֵי מוֹת"], "Balak": ["בָּלָק"], "Bamidbar": ["בְּמִדְבַּר"], "Bechukotai": ["בְּחֻקֹּתַי"], "Beha'alotcha": ["בְּהַעֲלֹתְךָ"], "Behar": ["בְּהַר"], "Bereshit": ["בְּרֵאשִׁית"], "Beshalach": ["בְּשַׁלַּח"], "Bo": ["בֹּא"], "Chayei Sara": ["חַיֵּי שָֹרָה"], "Chukat": ["חֻקַּת"], "Devarim": ["דְּבָרִים"], "Eikev": ["עֵקֶב"], "Emor": ["אֱמוֹר"], "Ha'azinu": ["הַאֲזִינוּ"], "Kedoshim": ["קְדשִׁים"], "Ki Tavo": ["כִּי־תָבוֹא"], "Ki Teitzei": ["כִּי־תֵצֵא"], "Ki Tisa": ["כִּי תִשָּׂא"], "Korach": ["קֹרַח"], "Lech-Lecha": ["לֶךְ־לְךָ"], "Masei": ["מַסְעֵי"], "Matot": ["מַּטּוֹת"], "Metzora": ["מְּצֹרָע"], "Miketz": ["מִקֵּץ"], "Mishpatim": ["מִּשְׁפָּטִים"], "Nasso": ["נָשׂא"], "Nitzavim": ["נִצָּבִים"], "Noach": ["נֹחַ"], "Pekudei": ["פְקוּדֵי"], "Pinchas": ["פִּינְחָס"], "Re'eh": ["רְאֵה"], "Sh'lach": ["שְׁלַח־לְךָ"], "Shemot": ["שְׁמוֹת"], "Shmini": ["שְּׁמִינִי"], "Shoftim": ["שׁוֹפְטִים"], "Tazria": ["תַזְרִיעַ"], "Terumah": ["תְּרוּמָה"], "Tetzaveh": ["תְּצַוֶּה"], "Toldot": ["תּוֹלְדוֹת"], "Tzav": ["צַו"], "Vaera": ["וָאֵרָא"], "Vaetchanan": ["וָאֶתְחַנַּן"], "Vayakhel": ["וַיַּקְהֵל"], "Vayechi": ["וַיְחִי"], "Vayeilech": ["וַיֵּלֶךְ"], "Vayera": ["וַיֵּרָא"], "Vayeshev": ["וַיֵּשֶׁב"], "Vayetzei": ["וַיֵּצֵא"], "Vayigash": ["וַיִּגַּשׁ"], "Vayikra": ["וַיִּקְרָא"], "Vayishlach": ["וַיִּשְׁלַח"], "Vezot Haberakhah": ["וְזֹאת הַבְּרָכָה"], "Yitro": ["יִתְרוֹ"], "Asara B'Tevet": ["עֲשָׂרָה בְּטֵבֵת"], "Candle lighting": ["הַדְלָקַת נֵרוֹת"], "Chanukah": ["חֲנוּכָּה"], "Chanukah: 1 Candle": ["חֲנוּכָּה: א׳ נֵר"], "Chanukah: 2 Candles": ["חֲנוּכָּה: ב׳ נֵרוֹת"], "Chanukah: 3 Candles": ["חֲנוּכָּה: ג׳ נֵרוֹת"], "Chanukah: 4 Candles": ["חֲנוּכָּה: ד׳ נֵרוֹת"], "Chanukah: 5 Candles": ["חֲנוּכָּה: ה׳ נֵרוֹת"], "Chanukah: 6 Candles": ["חֲנוּכָּה: ו׳ נֵרוֹת"], "Chanukah: 7 Candles": ["חֲנוּכָּה: ז׳ נֵרוֹת"], "Chanukah: 8 Candles": ["חֲנוּכָּה: ח׳ נֵרוֹת"], "Chanukah: 8th Day": ["חֲנוּכָּה: יוֹם ח׳"], "Days of the Omer": ["סְפִירַת הָעוֹמֶר"], "Omer": ["עוֹמֶר"], "day of the Omer": ["בָּעוֹמֶר"], "Erev Pesach": ["עֶרֶב פֶּסַח"], "Erev Purim": ["עֶרֶב פּוּרִים"], "Erev Rosh Hashana": ["עֶרֶב רֹאשׁ הַשָּׁנָה"], "Erev Shavuot": ["עֶרֶב שָׁבוּעוֹת"], "Erev Simchat Torah": ["עֶרֶב שִׂמְחַת תּוֹרָה"], "Erev Sukkot": ["עֶרֶב סוּכּוֹת"], "Erev Tish'a B'Av": ["עֶרֶב תִּשְׁעָה בְּאָב"], "Erev Yom Kippur": ["עֶרֶב יוֹם כִּפּוּר"], "Havdalah": ["הַבְדָּלָה"], "Lag BaOmer": ["ל״ג בָּעוֹמֶר"], "Leil Selichot": ["סליחות"], "Pesach": ["פֶּסַח"], "Pesach I": ["פֶּסַח א׳"], "Pesach II": ["פֶּסַח ב׳"], "Pesach II (CH''M)": ["פֶּסַח ב׳ (חוה״מ)"], "Pesach III (CH''M)": ["פֶּסַח ג׳ (חוה״מ)"], "Pesach IV (CH''M)": ["פֶּסַח ד׳ (חוה״מ)"], "Pesach Sheni": ["פֶּסַח שני"], "Pesach V (CH''M)": ["פֶּסַח ה׳ (חוה״מ)"], "Pesach VI (CH''M)": ["פֶּסַח ו׳ (חוה״מ)"], "Pesach VII": ["פֶּסַח ז׳"], "Pesach VIII": ["פֶּסַח ח׳"], "Purim": ["פּוּרִים"], "Purim Katan": ["פּוּרִים קָטָן"], "Rosh Chodesh %s": ["רֹאשׁ חוֹדֶשׁ %s"], "Rosh Chodesh": ["רֹאשׁ חוֹדֶשׁ"], "Rosh Hashana": ["רֹאשׁ הַשָּׁנָה"], "Rosh Hashana I": ["רֹאשׁ הַשָּׁנָה א׳"], "Rosh Hashana II": ["רֹאשׁ הַשָּׁנָה ב׳"], "Shabbat Chazon": ["שַׁבָּת חֲזוֹן"], "Shabbat HaChodesh": ["שַׁבָּת הַחֹדֶשׁ"], "Shabbat HaGadol": ["שַׁבָּת הַגָּדוֹל"], "Shabbat Nachamu": ["שַׁבָּת נַחֲמוּ"], "Shabbat Parah": ["שַׁבָּת פּרה"], "Shabbat Shekalim": ["שַׁבָּת שְׁקָלִים"], "Shabbat Shuva": ["שַׁבָּת שׁוּבָה"], "Shabbat Zachor": ["שַׁבָּת זָכוֹר"], "Shavuot": ["שָׁבוּעוֹת"], "Shavuot I": ["שָׁבוּעוֹת א׳"], "Shavuot II": ["שָׁבוּעוֹת ב׳"], "Shmini Atzeret": ["שְׁמִינִי עֲצֶרֶת"], "Shushan Purim": ["שׁוּשָׁן פּוּרִים"], "Sigd": ["סיגד"], "Simchat Torah": ["שִׂמְחַת תּוֹרָה"], "Sukkot": ["סוּכּוֹת"], "Sukkot I": ["סוּכּוֹת א׳"], "Sukkot II": ["סוּכּוֹת ב׳"], "Sukkot II (CH''M)": ["סוּכּוֹת ב׳ (חוה״מ)"], "Sukkot III (CH''M)": ["סוּכּוֹת ג׳ (חוה״מ)"], "Sukkot IV (CH''M)": ["סוּכּוֹת ד׳ (חוה״מ)"], "Sukkot V (CH''M)": ["סוּכּוֹת ה׳ (חוה״מ)"], "Sukkot VI (CH''M)": ["סוּכּוֹת ו׳ (חוה״מ)"], "Sukkot VII (Hoshana Raba)": ["סוּכּוֹת ז׳ (הוֹשַׁעְנָא רַבָּה)"], "Ta'anit Bechorot": ["תַּעֲנִית בְּכוֹרוֹת"], "Ta'anit Esther": ["תַּעֲנִית אֶסְתֵּר"], "Tish'a B'Av": ["תִּשְׁעָה בְּאָב"], "Tu B'Av": ["טוּ בְּאָב"], "Tu BiShvat": ["טוּ בִּשְׁבָט"], "Tu B'Shvat": ["טוּ בִּשְׁבָט"], "Tzom Gedaliah": ["צוֹם גְּדַלְיָה"], "Tzom Tammuz": ["צוֹם תָּמוּז"], "Yom HaAtzma'ut": ["יוֹם הָעַצְמָאוּת"], "Yom HaShoah": ["יוֹם הַשּׁוֹאָה"], "Yom HaZikaron": ["יוֹם הַזִּכָּרוֹן"], "Yom Kippur": ["יוֹם כִּפּוּר"], "Yom Yerushalayim": ["יוֹם יְרוּשָׁלַיִם"], "Yom HaAliyah": ["יוֹם הַעֲלִיָּה"], "Yom HaAliyah School Observance": ["שְׁמִירָת בֵּית הַסֵפֶר לְיוֹם הַעֲלִיָּה"], "Rosh Chodesh Adar": ["רֹאשׁ חוֹדֶשׁ אַדָר"], "Rosh Chodesh Adar I": ["רֹאשׁ חוֹדֶשׁ אַדָר א׳"], "Rosh Chodesh Adar II": ["רֹאשׁ חוֹדֶשׁ אַדָר ב׳"], "Rosh Chodesh Av": ["רֹאשׁ חוֹדֶשׁ אָב"], "Rosh Chodesh Cheshvan": ["רֹאשׁ חוֹדֶשׁ חֶשְׁוָן"], "Rosh Chodesh Elul": ["רֹאשׁ חוֹדֶשׁ אֱלוּל"], "Rosh Chodesh Iyyar": ["רֹאשׁ חוֹדֶשׁ אִיָיר"], "Rosh Chodesh Kislev": ["רֹאשׁ חוֹדֶשׁ כִּסְלֵו"], "Rosh Chodesh Nisan": ["רֹאשׁ חוֹדֶשׁ נִיסָן"], "Rosh Chodesh Sh'vat": ["רֹאשׁ חוֹדֶשׁ שְׁבָט"], "Rosh Chodesh Sivan": ["רֹאשׁ חוֹדֶשׁ סִיוָן"], "Rosh Chodesh Tamuz": ["רֹאשׁ חוֹדֶשׁ תָּמוּז"], "Rosh Chodesh Tevet": ["רֹאשׁ חוֹדֶשׁ טֵבֵת"], "min": ["דַּקּוֹת"], "Fast begins": ["תחילת הַצוֹם"], "Fast ends": ["סִיּוּם הַצוֹם"], "Rosh Hashana LaBehemot": ["רֹאשׁ הַשָּׁנָה לְמַעְשַׂר בְּהֵמָה"], "Tish'a B'Av (observed)": ["תִּשְׁעָה בְּאָב נִדחֶה"], "Shabbat Mevarchim Chodesh": ["שַׁבָּת מְבָרְכִים חוֹדֶשׁ"], "Shabbat Shirah": ["שַׁבָּת שִׁירָה"], "Chatzot HaLailah": ["חֲצוֹת הַלַיְלָה"], "Alot haShachar": ["עֲלוֹת הַשַּׁחַר"], "Misheyakir": ["מִשֶּׁיַּכִּיר"], "Misheyakir Machmir": ["מִשֶּׁיַּכִּיר מַחמִיר"], "Dawn": ["דִּימְדּוּמֵי בּוֹקֵר"], "Sunrise": ["הַנֵץ הַחַמָּה"], "Kriat Shema, sof zeman": ["סוֹף זְמַן קְרִיאַת שְׁמַע גר״א"], "Tefilah, sof zeman": ["סוֹף זְמַן תְּפִלָּה גר״א"], "Kriat Shema, sof zeman (MGA)": ["סוֹף זְמַן קְרִיאַת שְׁמַע מג״א"], "Tefilah, sof zeman (MGA)": ["סוֹף זְמַן תְּפִלָּה מג״א"], "Chatzot hayom": ["חֲצוֹת הַיּוֹם"], "Mincha Gedolah": ["מִנְחָה גְּדוֹלָה"], "Mincha Ketanah": ["מִנְחָה קְטַנָּה"], "Plag HaMincha": ["פְּלַג הַמִּנְחָה"], "Dusk": ["דִּימְדּוּמֵי עֶרֶב"], "Sunset": ["שְׁקִיעָה"], "Nightfall - End of ordained fasts": ["לַיְלָה - גמר תעניות דרבנן"], "Tzeit HaKochavim": ["צֵאת הַכּוֹכָבִים"], "Lovingkindness": ["חֶֽסֶד"], "Might": ["גְבוּרָה"], "Beauty": ["תִּפְאֶֽרֶת"], "Eternity": ["נֶּֽצַח"], "Splendor": ["הוֹד"], "Foundation": ["יְּסוֹד"], "Majesty": ["מַּלְכוּת"], "day": ["יוֹם"], "Yom Kippur Katan": ["יוֹם כִּפּוּר קָטָן"], "Yizkor": ["יִזְכּוֹר"], "Family Day": ["יוֹם הַמִּשׁפָּחָה"], "Yitzhak Rabin Memorial Day": ["יוֹם הַזִּכָּרוֹן ליצחק רבין"], "Jabotinsky Day": ["יוֹם ז׳בוטינסקי"], "Herzl Day": ["יוֹם הרצל"], "Ben-Gurion Day": ["יוֹם בן־גוריון"], "Hebrew Language Day": ["יוֹם הַשָׂפָה הַעִברִית"], "Birkat Hachamah": ["בִרְכַּת הַחַמָּה"], "Shushan Purim Katan": ["שׁוּשָׁן פּוּרִים קָטָן"], "Purim Meshulash": ["פּוּרִים מְשׁוּלָּשׁ"], "after sunset": ["לְאַחַר הַשְׁקִיעָה"], "Yerushalmi": ["יְרוּשַׁלְמִי"], "Chag HaBanot": ["חַג הַבָּנוֹת"], "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": ["מַלְאָכִי"], "Psalms": ["תְּהִלִּים"], "Proverbs": ["מִשְׁלֵי"], "Job": ["אִיּוֹב"], "Song of Songs": ["שִׁיר הַשִּׁירִים"], "Ruth": ["רוּת"], "Lamentations": ["אֵיכָה"], "Ecclesiastes": ["קֹהֶלֶת"], "Esther": ["אֶסְתֵּר"], "Daniel": ["דָּנִיֵּאל"], "Ezra": ["עֶזְרָא"], "Nehemiah": ["נְחֶמְיָה"], "I Chronicles": ["דִברֵי הַיָמִים רִאשׁוֹן"], "II Chronicles": ["דִברֵי הַיָמִים שֵׁנִי"], "Molad": ["מוֹלָד הָלְּבָנָה"], "chalakim": ["חֲלָקִים"], "Pirkei Avot": ["פִּרְקֵי אָבוֹת"] } } };
|
|
1878
|
+
|
|
1879
|
+
var noNikudOverride = { "headers": { "plural-forms": "nplurals=2; plural=(n != 1);", "language": "he-x-NoNikud" }, "contexts": { "": { "Korach": ["קורח"] } } };
|
|
14
1880
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
1881
|
+
Locale.addTranslations('he', poHe);
|
|
1882
|
+
Locale.addTranslations('h', poHe);
|
|
1883
|
+
Locale.addTranslations('ashkenazi', poAshkenazi);
|
|
1884
|
+
Locale.addTranslations('a', poAshkenazi);
|
|
19
1885
|
/* Hebrew without nikkud */
|
|
20
1886
|
const heStrs = poHe.contexts[''];
|
|
21
1887
|
const heNoNikud = {};
|
|
22
1888
|
for (const [key, val] of Object.entries(heStrs)) {
|
|
23
|
-
heNoNikud[key] = [
|
|
1889
|
+
heNoNikud[key] = [Locale.hebrewStripNikkud(val[0])];
|
|
24
1890
|
}
|
|
25
1891
|
const poHeNoNikud = {
|
|
26
1892
|
headers: poHe.headers,
|
|
27
1893
|
contexts: { '': heNoNikud },
|
|
28
1894
|
};
|
|
29
|
-
|
|
1895
|
+
Locale.addTranslations('he-x-NoNikud', poHeNoNikud);
|
|
1896
|
+
Locale.addTranslations('he-x-NoNikud', noNikudOverride);
|
|
30
1897
|
|
|
31
1898
|
/**
|
|
32
1899
|
* Holiday flags for Event. These flags are typically
|
|
@@ -126,7 +1993,7 @@ class Event {
|
|
|
126
1993
|
* @param [attrs={}] optional additional attributes (e.g. `eventTimeStr`, `cholHaMoedDay`)
|
|
127
1994
|
*/
|
|
128
1995
|
constructor(date, desc, mask = 0, attrs) {
|
|
129
|
-
if (!
|
|
1996
|
+
if (!HDate.isHDate(date)) {
|
|
130
1997
|
throw new TypeError(`Invalid Event date: ${date}`);
|
|
131
1998
|
}
|
|
132
1999
|
else if (typeof desc !== 'string') {
|
|
@@ -170,7 +2037,7 @@ class Event {
|
|
|
170
2037
|
* @param [locale] Optional locale name (defaults to active locale).
|
|
171
2038
|
*/
|
|
172
2039
|
render(locale) {
|
|
173
|
-
return
|
|
2040
|
+
return Locale.gettext(this.desc, locale);
|
|
174
2041
|
}
|
|
175
2042
|
/**
|
|
176
2043
|
* Returns a brief (translated) description of this event.
|
|
@@ -284,7 +2151,7 @@ class HebrewDateEvent extends Event {
|
|
|
284
2151
|
*/
|
|
285
2152
|
render(locale) {
|
|
286
2153
|
const locale1 = locale === null || locale === void 0 ? void 0 : locale.toLowerCase();
|
|
287
|
-
const locale0 = locale1 !== null && locale1 !== void 0 ? locale1 :
|
|
2154
|
+
const locale0 = locale1 !== null && locale1 !== void 0 ? locale1 : Locale.getLocaleName();
|
|
288
2155
|
const hd = this.getDate();
|
|
289
2156
|
switch (locale0) {
|
|
290
2157
|
case 'h':
|
|
@@ -303,8 +2170,8 @@ class HebrewDateEvent extends Event {
|
|
|
303
2170
|
renderBriefHebrew(locale) {
|
|
304
2171
|
const hd = this.getDate();
|
|
305
2172
|
const dd = hd.getDate();
|
|
306
|
-
const mm =
|
|
307
|
-
return
|
|
2173
|
+
const mm = Locale.gettext(hd.getMonthName(), locale);
|
|
2174
|
+
return gematriya(dd) + ' ' + mm;
|
|
308
2175
|
}
|
|
309
2176
|
/**
|
|
310
2177
|
* @param [locale] Optional locale name (defaults to active locale).
|
|
@@ -318,9 +2185,9 @@ class HebrewDateEvent extends Event {
|
|
|
318
2185
|
*/
|
|
319
2186
|
renderBrief(locale) {
|
|
320
2187
|
const locale1 = locale === null || locale === void 0 ? void 0 : locale.toLowerCase();
|
|
321
|
-
const locale0 = locale1 !== null && locale1 !== void 0 ? locale1 :
|
|
2188
|
+
const locale0 = locale1 !== null && locale1 !== void 0 ? locale1 : Locale.getLocaleName();
|
|
322
2189
|
const hd = this.getDate();
|
|
323
|
-
if (hd.getMonth() ===
|
|
2190
|
+
if (hd.getMonth() === months.TISHREI && hd.getDate() === 1) {
|
|
324
2191
|
return this.render(locale0);
|
|
325
2192
|
}
|
|
326
2193
|
switch (locale0) {
|
|
@@ -334,6 +2201,1106 @@ class HebrewDateEvent extends Event {
|
|
|
334
2201
|
}
|
|
335
2202
|
}
|
|
336
2203
|
|
|
2204
|
+
/**
|
|
2205
|
+
* java.lang.Math.toRadians
|
|
2206
|
+
* @private
|
|
2207
|
+
* @param degrees
|
|
2208
|
+
*/
|
|
2209
|
+
function degreesToRadians(degrees) {
|
|
2210
|
+
return (degrees * Math.PI) / 180;
|
|
2211
|
+
}
|
|
2212
|
+
/**
|
|
2213
|
+
* java.lang.Math.toDegrees
|
|
2214
|
+
* @private
|
|
2215
|
+
* @param radians
|
|
2216
|
+
*/
|
|
2217
|
+
function radiansToDegrees(radians) {
|
|
2218
|
+
return (radians * 180) / Math.PI;
|
|
2219
|
+
}
|
|
2220
|
+
/**
|
|
2221
|
+
* A class that contains location information such as latitude and longitude required for astronomical calculations. The
|
|
2222
|
+
* elevation field may not be used by some calculation engines and would be ignored if set.
|
|
2223
|
+
*
|
|
2224
|
+
* @author © Eliyahu Hershfeld 2004 - 2016
|
|
2225
|
+
* @version 1.1
|
|
2226
|
+
*/
|
|
2227
|
+
class GeoLocation {
|
|
2228
|
+
/**
|
|
2229
|
+
* GeoLocation constructor with parameters for all required fields.
|
|
2230
|
+
*
|
|
2231
|
+
* @param {string} name
|
|
2232
|
+
* The location name for display use such as "Lakewood, NJ"
|
|
2233
|
+
* @param {number} latitude
|
|
2234
|
+
* the latitude in a double format such as 40.095965 for Lakewood, NJ.
|
|
2235
|
+
* <b>Note: </b> For latitudes south of the equator, a negative value should be used.
|
|
2236
|
+
* @param {number} longitude
|
|
2237
|
+
* double the longitude in a double format such as -74.222130 for Lakewood, NJ.
|
|
2238
|
+
* <b>Note: </b> For longitudes west of the <a href="http://en.wikipedia.org/wiki/Prime_Meridian">Prime
|
|
2239
|
+
* Meridian </a> (Greenwich), a negative value should be used.
|
|
2240
|
+
* @param {number} elevation
|
|
2241
|
+
* the elevation above sea level in Meters. Elevation is not used in most algorithms used for calculating
|
|
2242
|
+
* sunrise and set.
|
|
2243
|
+
* @param {string} timeZoneId
|
|
2244
|
+
* the <code>TimeZone</code> for the location.
|
|
2245
|
+
*/
|
|
2246
|
+
constructor(name, latitude, longitude, elevation, timeZoneId) {
|
|
2247
|
+
/**
|
|
2248
|
+
* @private
|
|
2249
|
+
*/
|
|
2250
|
+
this.locationName = null;
|
|
2251
|
+
this.setLocationName(name);
|
|
2252
|
+
this.setLatitude(latitude);
|
|
2253
|
+
this.setLongitude(longitude);
|
|
2254
|
+
this.setElevation(elevation);
|
|
2255
|
+
this.setTimeZone(timeZoneId);
|
|
2256
|
+
}
|
|
2257
|
+
/**
|
|
2258
|
+
* Method to get the elevation in Meters.
|
|
2259
|
+
*
|
|
2260
|
+
* @return {number} Returns the elevation in Meters.
|
|
2261
|
+
*/
|
|
2262
|
+
getElevation() {
|
|
2263
|
+
return this.elevation;
|
|
2264
|
+
}
|
|
2265
|
+
/**
|
|
2266
|
+
* Method to set the elevation in Meters <b>above </b> sea level.
|
|
2267
|
+
*
|
|
2268
|
+
* @param {number} elevation
|
|
2269
|
+
* The elevation to set in Meters. An Error will be thrown if the value is a negative.
|
|
2270
|
+
*/
|
|
2271
|
+
setElevation(elevation) {
|
|
2272
|
+
if (typeof elevation !== 'number')
|
|
2273
|
+
throw new TypeError('Invalid elevation');
|
|
2274
|
+
if (elevation < 0) {
|
|
2275
|
+
throw new RangeError(`elevation ${elevation} must be zero or positive`);
|
|
2276
|
+
}
|
|
2277
|
+
this.elevation = elevation;
|
|
2278
|
+
}
|
|
2279
|
+
setLatitude(latitude) {
|
|
2280
|
+
if (typeof latitude !== 'number')
|
|
2281
|
+
throw new TypeError('Invalid latitude');
|
|
2282
|
+
if (latitude < -90 || latitude > 90) {
|
|
2283
|
+
throw new RangeError(`Latitude ${latitude} out of range [-90,90]`);
|
|
2284
|
+
}
|
|
2285
|
+
this.latitude = latitude;
|
|
2286
|
+
}
|
|
2287
|
+
/**
|
|
2288
|
+
* @return {number} Returns the latitude.
|
|
2289
|
+
*/
|
|
2290
|
+
getLatitude() {
|
|
2291
|
+
return this.latitude;
|
|
2292
|
+
}
|
|
2293
|
+
setLongitude(longitude) {
|
|
2294
|
+
if (typeof longitude !== 'number')
|
|
2295
|
+
throw new TypeError('Invalid longitude');
|
|
2296
|
+
if (longitude < -180 || longitude > 180) {
|
|
2297
|
+
throw new RangeError(`Longitude ${longitude} out of range [-180,180]`);
|
|
2298
|
+
}
|
|
2299
|
+
this.longitude = longitude;
|
|
2300
|
+
}
|
|
2301
|
+
/**
|
|
2302
|
+
* @return {number} Returns the longitude.
|
|
2303
|
+
*/
|
|
2304
|
+
getLongitude() {
|
|
2305
|
+
return this.longitude;
|
|
2306
|
+
}
|
|
2307
|
+
/**
|
|
2308
|
+
* @return {string|null} Returns the location name.
|
|
2309
|
+
*/
|
|
2310
|
+
getLocationName() {
|
|
2311
|
+
return this.locationName;
|
|
2312
|
+
}
|
|
2313
|
+
/**
|
|
2314
|
+
* @param {string|null} name
|
|
2315
|
+
* The setter method for the display name.
|
|
2316
|
+
*/
|
|
2317
|
+
setLocationName(name) {
|
|
2318
|
+
this.locationName = name;
|
|
2319
|
+
}
|
|
2320
|
+
/**
|
|
2321
|
+
* @return {string} Returns the timeZone.
|
|
2322
|
+
*/
|
|
2323
|
+
getTimeZone() {
|
|
2324
|
+
return this.timeZoneId;
|
|
2325
|
+
}
|
|
2326
|
+
/**
|
|
2327
|
+
* Method to set the TimeZone.
|
|
2328
|
+
* @param {string} timeZoneId
|
|
2329
|
+
* The timeZone to set.
|
|
2330
|
+
*/
|
|
2331
|
+
setTimeZone(timeZoneId) {
|
|
2332
|
+
if (!timeZoneId) {
|
|
2333
|
+
throw new RangeError('Invalid timeZoneId');
|
|
2334
|
+
}
|
|
2335
|
+
this.timeZoneId = timeZoneId;
|
|
2336
|
+
}
|
|
2337
|
+
}
|
|
2338
|
+
/**
|
|
2339
|
+
* The commonly used average solar refraction. Calendrical Calculations lists a more accurate global average of
|
|
2340
|
+
* 34.478885263888294
|
|
2341
|
+
* @private
|
|
2342
|
+
*/
|
|
2343
|
+
const refraction = 34 / 60;
|
|
2344
|
+
// private double refraction = 34.478885263888294 / 60d;
|
|
2345
|
+
/**
|
|
2346
|
+
* The commonly used average solar radius in minutes of a degree.
|
|
2347
|
+
* @private
|
|
2348
|
+
*/
|
|
2349
|
+
const solarRadius = 16 / 60;
|
|
2350
|
+
/**
|
|
2351
|
+
* The commonly used average earth radius in KM. At this time, this only affects elevation adjustment and not the
|
|
2352
|
+
* sunrise and sunset calculations. The value currently defaults to 6356.9 KM.
|
|
2353
|
+
* @private
|
|
2354
|
+
*/
|
|
2355
|
+
const earthRadius = 6356.9; // in KM
|
|
2356
|
+
/**
|
|
2357
|
+
* Implementation of sunrise and sunset methods to calculate astronomical times based on the <a
|
|
2358
|
+
* href="http://noaa.gov">NOAA</a> algorithm. This calculator uses the Java algorithm based on the implementation by <a
|
|
2359
|
+
* href="http://noaa.gov">NOAA - National Oceanic and Atmospheric Administration</a>'s <a href =
|
|
2360
|
+
* "http://www.srrb.noaa.gov/highlights/sunrise/sunrise.html">Surface Radiation Research Branch</a>. NOAA's <a
|
|
2361
|
+
* href="http://www.srrb.noaa.gov/highlights/sunrise/solareqns.PDF">implementation</a> is based on equations from <a
|
|
2362
|
+
* href="http://www.willbell.com/math/mc1.htm">Astronomical Algorithms</a> by <a
|
|
2363
|
+
* href="http://en.wikipedia.org/wiki/Jean_Meeus">Jean Meeus</a>. Added to the algorithm is an adjustment of the zenith
|
|
2364
|
+
* to account for elevation. The algorithm can be found in the <a
|
|
2365
|
+
* href="http://en.wikipedia.org/wiki/Sunrise_equation">Wikipedia Sunrise Equation</a> article.
|
|
2366
|
+
*
|
|
2367
|
+
* @author © Eliyahu Hershfeld 2011 - 2019
|
|
2368
|
+
*/
|
|
2369
|
+
class NOAACalculator {
|
|
2370
|
+
/**
|
|
2371
|
+
* A constructor that takes in <a href="http://en.wikipedia.org/wiki/Geolocation">geolocation</a> information as a
|
|
2372
|
+
* parameter.
|
|
2373
|
+
*
|
|
2374
|
+
* @param {GeoLocation} geoLocation
|
|
2375
|
+
* The location information used for calculating astronomical sun times.
|
|
2376
|
+
* @param {Temporal.PlainDate} date
|
|
2377
|
+
*/
|
|
2378
|
+
constructor(geoLocation, date) {
|
|
2379
|
+
this.date = date;
|
|
2380
|
+
this.geoLocation = geoLocation;
|
|
2381
|
+
}
|
|
2382
|
+
/**
|
|
2383
|
+
* The getSunrise method Returns a `Date` representing the
|
|
2384
|
+
* {@link getElevationAdjustment elevation adjusted} sunrise time. The zenith used
|
|
2385
|
+
* for the calculation uses {@link GEOMETRIC_ZENITH geometric zenith} of 90° plus
|
|
2386
|
+
* {@link getElevationAdjustment}. This is adjusted
|
|
2387
|
+
* to add approximately 50/60 of a degree to account for 34 archminutes of refraction
|
|
2388
|
+
* and 16 archminutes for the sun's radius for a total of {@link adjustZenith 90.83333°}.
|
|
2389
|
+
*
|
|
2390
|
+
* @return {Temporal.ZonedDateTime | null} the `Date` representing the exact sunrise time. If the calculation can't be computed such as
|
|
2391
|
+
* in the Arctic Circle where there is at least one day a year where the sun does not rise, and one where it
|
|
2392
|
+
* does not set, a null will be returned. See detailed explanation on top of the page.
|
|
2393
|
+
* @see adjustZenith
|
|
2394
|
+
* @see getSeaLevelSunrise()
|
|
2395
|
+
* @see getUTCSunrise
|
|
2396
|
+
*/
|
|
2397
|
+
getSunrise() {
|
|
2398
|
+
const sunrise = this.getUTCSunrise0(NOAACalculator.GEOMETRIC_ZENITH);
|
|
2399
|
+
if (isNaN(sunrise))
|
|
2400
|
+
return null;
|
|
2401
|
+
return this.getDateFromTime(sunrise, true);
|
|
2402
|
+
}
|
|
2403
|
+
/**
|
|
2404
|
+
* A method that returns the sunrise without {@link getElevationAdjustment elevation
|
|
2405
|
+
* adjustment}. Non-sunrise and sunset calculations such as dawn and dusk, depend on the amount of visible light,
|
|
2406
|
+
* something that is not affected by elevation. This method returns sunrise calculated at sea level. This forms the
|
|
2407
|
+
* base for dawn calculations that are calculated as a dip below the horizon before sunrise.
|
|
2408
|
+
*
|
|
2409
|
+
* @return {Temporal.ZonedDateTime | null} the `Date` representing the exact sea-level sunrise time. If the calculation can't be computed
|
|
2410
|
+
* such as in the Arctic Circle where there is at least one day a year where the sun does not rise, and one
|
|
2411
|
+
* where it does not set, a null will be returned. See detailed explanation on top of the page.
|
|
2412
|
+
* @see getSunrise
|
|
2413
|
+
* @see getUTCSeaLevelSunrise
|
|
2414
|
+
* @see getSeaLevelSunset()
|
|
2415
|
+
*/
|
|
2416
|
+
getSeaLevelSunrise() {
|
|
2417
|
+
const sunrise = this.getUTCSeaLevelSunrise(NOAACalculator.GEOMETRIC_ZENITH);
|
|
2418
|
+
if (isNaN(sunrise))
|
|
2419
|
+
return null;
|
|
2420
|
+
return this.getDateFromTime(sunrise, true);
|
|
2421
|
+
}
|
|
2422
|
+
/**
|
|
2423
|
+
* A method that returns the beginning of civil twilight (dawn) using a zenith of {@link CIVIL_ZENITH 96°}.
|
|
2424
|
+
*
|
|
2425
|
+
* @return {Temporal.ZonedDateTime | null} The `Date` of the beginning of civil twilight using a zenith of 96°. If the calculation
|
|
2426
|
+
* can't be computed, null will be returned. See detailed explanation on top of the page.
|
|
2427
|
+
* @see CIVIL_ZENITH
|
|
2428
|
+
*/
|
|
2429
|
+
getBeginCivilTwilight() {
|
|
2430
|
+
return this.getSunriseOffsetByDegrees(NOAACalculator.CIVIL_ZENITH);
|
|
2431
|
+
}
|
|
2432
|
+
/**
|
|
2433
|
+
* A method that returns the beginning of nautical twilight using a zenith of {@link NAUTICAL_ZENITH 102°}.
|
|
2434
|
+
*
|
|
2435
|
+
* @return {Temporal.ZonedDateTime | null} The `Date` of the beginning of nautical twilight using a zenith of 102°. If the
|
|
2436
|
+
* calculation can't be computed null will be returned. See detailed explanation on top of the page.
|
|
2437
|
+
* @see NAUTICAL_ZENITH
|
|
2438
|
+
*/
|
|
2439
|
+
getBeginNauticalTwilight() {
|
|
2440
|
+
return this.getSunriseOffsetByDegrees(NOAACalculator.NAUTICAL_ZENITH);
|
|
2441
|
+
}
|
|
2442
|
+
/**
|
|
2443
|
+
* A method that returns the beginning of astronomical twilight using a zenith of {@link ASTRONOMICAL_ZENITH
|
|
2444
|
+
* 108°}.
|
|
2445
|
+
*
|
|
2446
|
+
* @return {Temporal.ZonedDateTime | null} The `Date` of the beginning of astronomical twilight using a zenith of 108°. If the
|
|
2447
|
+
* calculation can't be computed, null will be returned. See detailed explanation on top of the page.
|
|
2448
|
+
* @see ASTRONOMICAL_ZENITH
|
|
2449
|
+
*/
|
|
2450
|
+
getBeginAstronomicalTwilight() {
|
|
2451
|
+
return this.getSunriseOffsetByDegrees(NOAACalculator.ASTRONOMICAL_ZENITH);
|
|
2452
|
+
}
|
|
2453
|
+
/**
|
|
2454
|
+
* The getSunset method Returns a `Date` representing the
|
|
2455
|
+
* {@link getElevationAdjustment elevation adjusted} sunset time. The zenith used for
|
|
2456
|
+
* the calculation uses {@link GEOMETRIC_ZENITH geometric zenith} of 90° plus
|
|
2457
|
+
* {@link getElevationAdjustment}. This is adjusted
|
|
2458
|
+
* to add approximately 50/60 of a degree to account for 34 archminutes of refraction
|
|
2459
|
+
* and 16 archminutes for the sun's radius for a total of {@link adjustZenith 90.83333°}.
|
|
2460
|
+
* Note:
|
|
2461
|
+
* In certain cases the calculates sunset will occur before sunrise. This will typically happen when a timezone
|
|
2462
|
+
* other than the local timezone is used (calculating Los Angeles sunset using a GMT timezone for example). In this
|
|
2463
|
+
* case the sunset date will be incremented to the following date.
|
|
2464
|
+
*
|
|
2465
|
+
* @return {Temporal.ZonedDateTime | null} The `Date` representing the exact sunset time. If the calculation can't be computed such as in
|
|
2466
|
+
* the Arctic Circle where there is at least one day a year where the sun does not rise, and one where it
|
|
2467
|
+
* does not set, a null will be returned. See detailed explanation on top of the page.
|
|
2468
|
+
* @see adjustZenith
|
|
2469
|
+
* @see getSeaLevelSunset()
|
|
2470
|
+
* @see getUTCSunset
|
|
2471
|
+
*/
|
|
2472
|
+
getSunset() {
|
|
2473
|
+
const sunset = this.getUTCSunset0(NOAACalculator.GEOMETRIC_ZENITH);
|
|
2474
|
+
if (isNaN(sunset))
|
|
2475
|
+
return null;
|
|
2476
|
+
return this.getDateFromTime(sunset, false);
|
|
2477
|
+
}
|
|
2478
|
+
/**
|
|
2479
|
+
* A method that returns the sunset without {@link getElevationAdjustment elevation
|
|
2480
|
+
* adjustment}. Non-sunrise and sunset calculations such as dawn and dusk, depend on the amount of visible light,
|
|
2481
|
+
* something that is not affected by elevation. This method returns sunset calculated at sea level. This forms the
|
|
2482
|
+
* base for dusk calculations that are calculated as a dip below the horizon after sunset.
|
|
2483
|
+
*
|
|
2484
|
+
* @return {Temporal.ZonedDateTime | null} The `Date` representing the exact sea-level sunset time. If the calculation can't be computed
|
|
2485
|
+
* such as in the Arctic Circle where there is at least one day a year where the sun does not rise, and one
|
|
2486
|
+
* where it does not set, a null will be returned. See detailed explanation on top of the page.
|
|
2487
|
+
* @see getSunset
|
|
2488
|
+
* @see getUTCSeaLevelSunset
|
|
2489
|
+
*/
|
|
2490
|
+
getSeaLevelSunset() {
|
|
2491
|
+
const sunset = this.getUTCSeaLevelSunset(NOAACalculator.GEOMETRIC_ZENITH);
|
|
2492
|
+
if (isNaN(sunset))
|
|
2493
|
+
return null;
|
|
2494
|
+
return this.getDateFromTime(sunset, false);
|
|
2495
|
+
}
|
|
2496
|
+
/**
|
|
2497
|
+
* A method that returns the end of civil twilight using a zenith of {@link CIVIL_ZENITH 96°}.
|
|
2498
|
+
*
|
|
2499
|
+
* @return {Temporal.ZonedDateTime | null} The `Date` of the end of civil twilight using a zenith of {@link CIVIL_ZENITH 96°}. If
|
|
2500
|
+
* the calculation can't be computed, null will be returned. See detailed explanation on top of the page.
|
|
2501
|
+
* @see CIVIL_ZENITH
|
|
2502
|
+
*/
|
|
2503
|
+
getEndCivilTwilight() {
|
|
2504
|
+
return this.getSunsetOffsetByDegrees(NOAACalculator.CIVIL_ZENITH);
|
|
2505
|
+
}
|
|
2506
|
+
/**
|
|
2507
|
+
* A method that returns the end of nautical twilight using a zenith of {@link NAUTICAL_ZENITH 102°}.
|
|
2508
|
+
*
|
|
2509
|
+
* @return {Temporal.ZonedDateTime | null} The `Date` of the end of nautical twilight using a zenith of {@link NAUTICAL_ZENITH 102°}
|
|
2510
|
+
* . If the calculation can't be computed, null will be returned. See detailed explanation on top of the
|
|
2511
|
+
* page.
|
|
2512
|
+
* @see NAUTICAL_ZENITH
|
|
2513
|
+
*/
|
|
2514
|
+
getEndNauticalTwilight() {
|
|
2515
|
+
return this.getSunsetOffsetByDegrees(NOAACalculator.NAUTICAL_ZENITH);
|
|
2516
|
+
}
|
|
2517
|
+
/**
|
|
2518
|
+
* A method that returns the end of astronomical twilight using a zenith of {@link ASTRONOMICAL_ZENITH 108°}.
|
|
2519
|
+
*
|
|
2520
|
+
* @return {Temporal.ZonedDateTime | null} The `Date` of the end of astronomical twilight using a zenith of {@link ASTRONOMICAL_ZENITH
|
|
2521
|
+
* 108°}. If the calculation can't be computed, null will be returned. See detailed explanation on top
|
|
2522
|
+
* of the page.
|
|
2523
|
+
* @see ASTRONOMICAL_ZENITH
|
|
2524
|
+
*/
|
|
2525
|
+
getEndAstronomicalTwilight() {
|
|
2526
|
+
return this.getSunsetOffsetByDegrees(NOAACalculator.ASTRONOMICAL_ZENITH);
|
|
2527
|
+
}
|
|
2528
|
+
/**
|
|
2529
|
+
* A utility method that returns a date offset by the offset time passed in. Please note that the level of light
|
|
2530
|
+
* during twilight is not affected by elevation, so if this is being used to calculate an offset before sunrise or
|
|
2531
|
+
* after sunset with the intent of getting a rough "level of light" calculation, the sunrise or sunset time passed
|
|
2532
|
+
* to this method should be sea level sunrise and sunset.
|
|
2533
|
+
*
|
|
2534
|
+
* @param {Temporal.ZonedDateTime | null} time
|
|
2535
|
+
* the start time
|
|
2536
|
+
* @param {number} offset
|
|
2537
|
+
* the offset in milliseconds to add to the time.
|
|
2538
|
+
* @return {Temporal.ZonedDateTime | null} the `Date` with the offset in milliseconds added to it
|
|
2539
|
+
*/
|
|
2540
|
+
static getTimeOffset(time, offset) {
|
|
2541
|
+
if (time === null || isNaN(offset)) {
|
|
2542
|
+
return null;
|
|
2543
|
+
}
|
|
2544
|
+
return time.add({ milliseconds: offset });
|
|
2545
|
+
}
|
|
2546
|
+
/**
|
|
2547
|
+
* A utility method that returns the time of an offset by degrees below or above the horizon of
|
|
2548
|
+
* {@link getSunrise() sunrise}. Note that the degree offset is from the vertical, so for a calculation of 14°
|
|
2549
|
+
* before sunrise, an offset of 14 + {@link GEOMETRIC_ZENITH} = 104 would have to be passed as a parameter.
|
|
2550
|
+
*
|
|
2551
|
+
* @param {number} offsetZenith
|
|
2552
|
+
* the degrees before {@link getSunrise} to use in the calculation. For time after sunrise use
|
|
2553
|
+
* negative numbers. Note that the degree offset is from the vertical, so for a calculation of 14°
|
|
2554
|
+
* before sunrise, an offset of 14 + {@link GEOMETRIC_ZENITH} = 104 would have to be passed as a
|
|
2555
|
+
* parameter.
|
|
2556
|
+
* @return {Temporal.ZonedDateTime | null} The `Date` of the offset after (or before) {@link getSunrise}. If the calculation
|
|
2557
|
+
* can't be computed such as in the Arctic Circle where there is at least one day a year where the sun does
|
|
2558
|
+
* not rise, and one where it does not set, a null will be returned. See detailed explanation on top of the
|
|
2559
|
+
* page.
|
|
2560
|
+
*/
|
|
2561
|
+
getSunriseOffsetByDegrees(offsetZenith) {
|
|
2562
|
+
const dawn = this.getUTCSunrise0(offsetZenith);
|
|
2563
|
+
if (isNaN(dawn))
|
|
2564
|
+
return null;
|
|
2565
|
+
return this.getDateFromTime(dawn, true);
|
|
2566
|
+
}
|
|
2567
|
+
/**
|
|
2568
|
+
* A utility method that returns the time of an offset by degrees below or above the horizon of {@link getSunset()
|
|
2569
|
+
* sunset}. Note that the degree offset is from the vertical, so for a calculation of 14° after sunset, an
|
|
2570
|
+
* offset of 14 + {@link GEOMETRIC_ZENITH} = 104 would have to be passed as a parameter.
|
|
2571
|
+
*
|
|
2572
|
+
* @param {number} offsetZenith
|
|
2573
|
+
* the degrees after {@link getSunset} to use in the calculation. For time before sunset use negative
|
|
2574
|
+
* numbers. Note that the degree offset is from the vertical, so for a calculation of 14° after
|
|
2575
|
+
* sunset, an offset of 14 + {@link GEOMETRIC_ZENITH} = 104 would have to be passed as a parameter.
|
|
2576
|
+
* @return {Temporal.ZonedDateTime | null} The `Date`of the offset after (or before) {@link getSunset}. If the calculation can't
|
|
2577
|
+
* be computed such as in the Arctic Circle where there is at least one day a year where the sun does not
|
|
2578
|
+
* rise, and one where it does not set, a null will be returned. See detailed explanation on top of the
|
|
2579
|
+
* page.
|
|
2580
|
+
*/
|
|
2581
|
+
getSunsetOffsetByDegrees(offsetZenith) {
|
|
2582
|
+
const sunset = this.getUTCSunset0(offsetZenith);
|
|
2583
|
+
if (isNaN(sunset))
|
|
2584
|
+
return null;
|
|
2585
|
+
return this.getDateFromTime(sunset, false);
|
|
2586
|
+
}
|
|
2587
|
+
/**
|
|
2588
|
+
* A method that returns the sunrise in UTC time without correction for time zone offset from GMT and without using
|
|
2589
|
+
* daylight savings time.
|
|
2590
|
+
*
|
|
2591
|
+
* @param {number} zenith
|
|
2592
|
+
* the degrees below the horizon. For time after sunrise use negative numbers.
|
|
2593
|
+
* @return {number} The time in the format: 18.75 for 18:45:00 UTC/GMT. If the calculation can't be computed such as in the
|
|
2594
|
+
* Arctic Circle where there is at least one day a year where the sun does not rise, and one where it does
|
|
2595
|
+
* not set, `NaN` will be returned. See detailed explanation on top of the page.
|
|
2596
|
+
*/
|
|
2597
|
+
getUTCSunrise0(zenith) {
|
|
2598
|
+
return this.getUTCSunrise(this.getAdjustedDate(), this.geoLocation, zenith, true);
|
|
2599
|
+
}
|
|
2600
|
+
/**
|
|
2601
|
+
* A method that returns the sunrise in UTC time without correction for time zone offset from GMT and without using
|
|
2602
|
+
* daylight savings time. Non-sunrise and sunset calculations such as dawn and dusk, depend on the amount of visible
|
|
2603
|
+
* light, something that is not affected by elevation. This method returns UTC sunrise calculated at sea level. This
|
|
2604
|
+
* forms the base for dawn calculations that are calculated as a dip below the horizon before sunrise.
|
|
2605
|
+
*
|
|
2606
|
+
* @param {number} zenith
|
|
2607
|
+
* the degrees below the horizon. For time after sunrise use negative numbers.
|
|
2608
|
+
* @return {number} The time in the format: 18.75 for 18:45:00 UTC/GMT. If the calculation can't be computed such as in the
|
|
2609
|
+
* Arctic Circle where there is at least one day a year where the sun does not rise, and one where it does
|
|
2610
|
+
* not set, `NaN` will be returned. See detailed explanation on top of the page.
|
|
2611
|
+
* @see getUTCSunrise
|
|
2612
|
+
* @see getUTCSeaLevelSunset
|
|
2613
|
+
*/
|
|
2614
|
+
getUTCSeaLevelSunrise(zenith) {
|
|
2615
|
+
return this.getUTCSunrise(this.getAdjustedDate(), this.geoLocation, zenith, false);
|
|
2616
|
+
}
|
|
2617
|
+
/**
|
|
2618
|
+
* A method that returns the sunset in UTC time without correction for time zone offset from GMT and without using
|
|
2619
|
+
* daylight savings time.
|
|
2620
|
+
*
|
|
2621
|
+
* @param {number} zenith
|
|
2622
|
+
* the degrees below the horizon. For time after sunset use negative numbers.
|
|
2623
|
+
* @return {number} The time in the format: 18.75 for 18:45:00 UTC/GMT. If the calculation can't be computed such as in the
|
|
2624
|
+
* Arctic Circle where there is at least one day a year where the sun does not rise, and one where it does
|
|
2625
|
+
* not set, `NaN` will be returned. See detailed explanation on top of the page.
|
|
2626
|
+
* @see getUTCSeaLevelSunset
|
|
2627
|
+
*/
|
|
2628
|
+
getUTCSunset0(zenith) {
|
|
2629
|
+
return this.getUTCSunset(this.getAdjustedDate(), this.geoLocation, zenith, true);
|
|
2630
|
+
}
|
|
2631
|
+
/**
|
|
2632
|
+
* A method that returns the sunset in UTC time without correction for elevation, time zone offset from GMT and
|
|
2633
|
+
* without using daylight savings time. Non-sunrise and sunset calculations such as dawn and dusk, depend on the
|
|
2634
|
+
* amount of visible light, something that is not affected by elevation. This method returns UTC sunset calculated
|
|
2635
|
+
* at sea level. This forms the base for dusk calculations that are calculated as a dip below the horizon after
|
|
2636
|
+
* sunset.
|
|
2637
|
+
*
|
|
2638
|
+
* @param {number} zenith
|
|
2639
|
+
* the degrees below the horizon. For time before sunset use negative numbers.
|
|
2640
|
+
* @return {number} The time in the format: 18.75 for 18:45:00 UTC/GMT. If the calculation can't be computed such as in the
|
|
2641
|
+
* Arctic Circle where there is at least one day a year where the sun does not rise, and one where it does
|
|
2642
|
+
* not set, `NaN` will be returned. See detailed explanation on top of the page.
|
|
2643
|
+
* @see getUTCSunset
|
|
2644
|
+
* @see getUTCSeaLevelSunrise
|
|
2645
|
+
*/
|
|
2646
|
+
getUTCSeaLevelSunset(zenith) {
|
|
2647
|
+
return this.getUTCSunset(this.getAdjustedDate(), this.geoLocation, zenith, false);
|
|
2648
|
+
}
|
|
2649
|
+
/**
|
|
2650
|
+
* Adjusts the <code>Calendar</code> to deal with edge cases where the location crosses the antimeridian.
|
|
2651
|
+
* @private
|
|
2652
|
+
* @see GeoLocation#getAntimeridianAdjustment()
|
|
2653
|
+
* @return the adjusted Calendar
|
|
2654
|
+
*/
|
|
2655
|
+
getAdjustedDate() {
|
|
2656
|
+
return this.date;
|
|
2657
|
+
}
|
|
2658
|
+
/**
|
|
2659
|
+
* Method to return the adjustment to the zenith required to account for the elevation. Since a person at a higher
|
|
2660
|
+
* elevation can see farther below the horizon, the calculation for sunrise / sunset is calculated below the horizon
|
|
2661
|
+
* used at sea level. This is only used for sunrise and sunset and not times before or after it such as
|
|
2662
|
+
* {@link getBeginNauticalTwilight() nautical twilight} since those
|
|
2663
|
+
* calculations are based on the level of available light at the given dip below the horizon, something that is not
|
|
2664
|
+
* affected by elevation, the adjustment should only made if the zenith == 90° {@link adjustZenith adjusted}
|
|
2665
|
+
* for refraction and solar radius. The algorithm used is
|
|
2666
|
+
*
|
|
2667
|
+
* <pre>
|
|
2668
|
+
* elevationAdjustment = Math.toDegrees(Math.acos(earthRadiusInMeters / (earthRadiusInMeters + elevationMeters)));
|
|
2669
|
+
* </pre>
|
|
2670
|
+
*
|
|
2671
|
+
* The source of this algorithm is <a href="http://www.calendarists.com">Calendrical Calculations</a> by Edward M.
|
|
2672
|
+
* Reingold and Nachum Dershowitz. An alternate algorithm that produces an almost identical (but not accurate)
|
|
2673
|
+
* result found in Ma'aglay Tzedek by Moishe Kosower and other sources is:
|
|
2674
|
+
*
|
|
2675
|
+
* <pre>
|
|
2676
|
+
* elevationAdjustment = 0.0347 * Math.sqrt(elevationMeters);
|
|
2677
|
+
* </pre>
|
|
2678
|
+
*
|
|
2679
|
+
* @param {number} elevation
|
|
2680
|
+
* elevation in Meters.
|
|
2681
|
+
* @return {number} the adjusted zenith
|
|
2682
|
+
*/
|
|
2683
|
+
getElevationAdjustment(elevation) {
|
|
2684
|
+
// double elevationAdjustment = 0.0347 * Math.sqrt(elevation);
|
|
2685
|
+
const elevationAdjustment = radiansToDegrees(Math.acos(earthRadius / (earthRadius + elevation / 1000)));
|
|
2686
|
+
return elevationAdjustment;
|
|
2687
|
+
}
|
|
2688
|
+
/**
|
|
2689
|
+
* Adjusts the zenith of astronomical sunrise and sunset to account for solar refraction, solar radius and
|
|
2690
|
+
* elevation. The value for Sun's zenith and true rise/set Zenith (used in this class and subclasses) is the angle
|
|
2691
|
+
* that the center of the Sun makes to a line perpendicular to the Earth's surface. If the Sun were a point and the
|
|
2692
|
+
* Earth were without an atmosphere, true sunset and sunrise would correspond to a 90° zenith. Because the Sun
|
|
2693
|
+
* is not a point, and because the atmosphere refracts light, this 90° zenith does not, in fact, correspond to
|
|
2694
|
+
* true sunset or sunrise, instead the centre of the Sun's disk must lie just below the horizon for the upper edge
|
|
2695
|
+
* to be obscured. This means that a zenith of just above 90° must be used. The Sun subtends an angle of 16
|
|
2696
|
+
* minutes of arc, and atmospheric refraction
|
|
2697
|
+
* accounts for 34 minutes or so, giving a total
|
|
2698
|
+
* of 50 arcminutes. The total value for ZENITH is 90+(5/6) or 90.8333333° for true sunrise/sunset. Since a
|
|
2699
|
+
* person at an elevation can see blow the horizon of a person at sea level, this will also adjust the zenith to
|
|
2700
|
+
* account for elevation if available. Note that this will only adjust the value if the zenith is exactly 90 degrees.
|
|
2701
|
+
* For values below and above this no correction is done. As an example, astronomical twilight is when the sun is
|
|
2702
|
+
* 18° below the horizon or {@link ASTRONOMICAL_ZENITH 108°
|
|
2703
|
+
* below the zenith}. This is traditionally calculated with none of the above mentioned adjustments. The same goes
|
|
2704
|
+
* for various <em>tzais</em> and <em>alos</em> times such as the
|
|
2705
|
+
* {@link ZmanimCalendar#ZENITH_16_POINT_1 16.1°} dip used in
|
|
2706
|
+
* {@link ComplexZmanimCalendar#getAlos16Point1Degrees}.
|
|
2707
|
+
*
|
|
2708
|
+
* @param {number} zenith
|
|
2709
|
+
* the azimuth below the vertical zenith of 90°. For sunset typically the {@link adjustZenith
|
|
2710
|
+
* zenith} used for the calculation uses geometric zenith of 90° and {@link adjustZenith adjusts}
|
|
2711
|
+
* this slightly to account for solar refraction and the sun's radius. Another example would be
|
|
2712
|
+
* {@link getEndNauticalTwilight} that passes
|
|
2713
|
+
* {@link NAUTICAL_ZENITH} to this method.
|
|
2714
|
+
* @param {number} elevation
|
|
2715
|
+
* elevation in Meters.
|
|
2716
|
+
* @return {number} The zenith adjusted to include the sun's radius, refracton
|
|
2717
|
+
* and {@link getElevationAdjustment elevation} adjustment. This will only be adjusted for
|
|
2718
|
+
* sunrise and sunset (if the zenith == 90°)
|
|
2719
|
+
* @see getElevationAdjustment
|
|
2720
|
+
*/
|
|
2721
|
+
adjustZenith(zenith, elevation) {
|
|
2722
|
+
let adjustedZenith = zenith;
|
|
2723
|
+
if (zenith === NOAACalculator.GEOMETRIC_ZENITH) {
|
|
2724
|
+
// only adjust if it is exactly sunrise or sunset
|
|
2725
|
+
adjustedZenith =
|
|
2726
|
+
zenith +
|
|
2727
|
+
(solarRadius + refraction + this.getElevationAdjustment(elevation));
|
|
2728
|
+
}
|
|
2729
|
+
return adjustedZenith;
|
|
2730
|
+
}
|
|
2731
|
+
/**
|
|
2732
|
+
* A method that calculates UTC sunrise as well as any time based on an angle above or below sunrise.
|
|
2733
|
+
* @param date
|
|
2734
|
+
* Used to calculate day of year.
|
|
2735
|
+
* @param geoLocation
|
|
2736
|
+
* The location information used for astronomical calculating sun times.
|
|
2737
|
+
* @param zenith
|
|
2738
|
+
* the azimuth below the vertical zenith of 90 degrees. for sunrise typically the {@link adjustZenith
|
|
2739
|
+
* zenith} used for the calculation uses geometric zenith of 90° and {@link adjustZenith adjusts}
|
|
2740
|
+
* this slightly to account for solar refraction and the sun's radius. Another example would be
|
|
2741
|
+
* {@link getBeginNauticalTwilight} that passes
|
|
2742
|
+
* {@link NAUTICAL_ZENITH} to this method.
|
|
2743
|
+
* @param adjustForElevation
|
|
2744
|
+
* Should the time be adjusted for elevation
|
|
2745
|
+
* @return The UTC time of sunrise in 24 hour format. 5:45:00 AM will return 5.75.0. If an error was encountered in
|
|
2746
|
+
* the calculation (expected behavior for some locations such as near the poles,
|
|
2747
|
+
* `NaN` will be returned.
|
|
2748
|
+
*/
|
|
2749
|
+
getUTCSunrise(date, geoLocation, zenith, adjustForElevation) {
|
|
2750
|
+
const elevation = adjustForElevation
|
|
2751
|
+
? geoLocation.getElevation()
|
|
2752
|
+
: 0;
|
|
2753
|
+
const adjustedZenith = this.adjustZenith(zenith, elevation);
|
|
2754
|
+
let sunrise = NOAACalculator.getSunriseUTC(NOAACalculator.getJulianDay(date), geoLocation.getLatitude(), -geoLocation.getLongitude(), adjustedZenith);
|
|
2755
|
+
sunrise = sunrise / 60;
|
|
2756
|
+
// ensure that the time is >= 0 and < 24
|
|
2757
|
+
while (sunrise < 0) {
|
|
2758
|
+
sunrise += 24;
|
|
2759
|
+
}
|
|
2760
|
+
while (sunrise >= 24) {
|
|
2761
|
+
sunrise -= 24;
|
|
2762
|
+
}
|
|
2763
|
+
return sunrise;
|
|
2764
|
+
}
|
|
2765
|
+
/**
|
|
2766
|
+
* A method that calculates UTC sunset as well as any time based on an angle above or below sunset.
|
|
2767
|
+
* @param date
|
|
2768
|
+
* Used to calculate day of year.
|
|
2769
|
+
* @param geoLocation
|
|
2770
|
+
* The location information used for astronomical calculating sun times.
|
|
2771
|
+
* @param zenith
|
|
2772
|
+
* the azimuth below the vertical zenith of 90°. For sunset typically the {@link adjustZenith
|
|
2773
|
+
* zenith} used for the calculation uses geometric zenith of 90° and {@link adjustZenith adjusts}
|
|
2774
|
+
* this slightly to account for solar refraction and the sun's radius. Another example would be
|
|
2775
|
+
* {@link getEndNauticalTwilight} that passes
|
|
2776
|
+
* {@link NAUTICAL_ZENITH} to this method.
|
|
2777
|
+
* @param adjustForElevation
|
|
2778
|
+
* Should the time be adjusted for elevation
|
|
2779
|
+
* @return The UTC time of sunset in 24 hour format. 5:45:00 AM will return 5.75.0. If an error was encountered in
|
|
2780
|
+
* the calculation (expected behavior for some locations such as near the poles,
|
|
2781
|
+
* `NaN` will be returned.
|
|
2782
|
+
*/
|
|
2783
|
+
getUTCSunset(date, geoLocation, zenith, adjustForElevation) {
|
|
2784
|
+
const elevation = adjustForElevation
|
|
2785
|
+
? geoLocation.getElevation()
|
|
2786
|
+
: 0;
|
|
2787
|
+
const adjustedZenith = this.adjustZenith(zenith, elevation);
|
|
2788
|
+
let sunset = NOAACalculator.getSunsetUTC(NOAACalculator.getJulianDay(date), geoLocation.getLatitude(), -geoLocation.getLongitude(), adjustedZenith);
|
|
2789
|
+
sunset = sunset / 60;
|
|
2790
|
+
// ensure that the time is >= 0 and < 24
|
|
2791
|
+
while (sunset < 0) {
|
|
2792
|
+
sunset += 24;
|
|
2793
|
+
}
|
|
2794
|
+
while (sunset >= 24) {
|
|
2795
|
+
sunset -= 24;
|
|
2796
|
+
}
|
|
2797
|
+
return sunset;
|
|
2798
|
+
}
|
|
2799
|
+
/**
|
|
2800
|
+
* A utility method that will allow the calculation of a temporal (solar) hour based on the sunrise and sunset
|
|
2801
|
+
* passed as parameters to this method. An example of the use of this method would be the calculation of a
|
|
2802
|
+
* non-elevation adjusted temporal hour by passing in {@link getSeaLevelSunrise() sea level sunrise} and
|
|
2803
|
+
* {@link getSeaLevelSunset() sea level sunset} as parameters.
|
|
2804
|
+
*
|
|
2805
|
+
* @param {Temporal.ZonedDateTime | null} startOfDay
|
|
2806
|
+
* The start of the day.
|
|
2807
|
+
* @param {Temporal.ZonedDateTime | null} endOfDay
|
|
2808
|
+
* The end of the day.
|
|
2809
|
+
*
|
|
2810
|
+
* @return {number} the <code>long</code> millisecond length of the temporal hour. If the calculation can't be computed a
|
|
2811
|
+
* `NaN` will be returned. See detailed explanation on top of the page.
|
|
2812
|
+
*
|
|
2813
|
+
* @see getTemporalHour()
|
|
2814
|
+
*/
|
|
2815
|
+
getTemporalHour(startOfDay = this.getSeaLevelSunrise(), endOfDay = this.getSeaLevelSunset()) {
|
|
2816
|
+
if (startOfDay === null || endOfDay === null) {
|
|
2817
|
+
return NaN;
|
|
2818
|
+
}
|
|
2819
|
+
const delta = endOfDay.epochMilliseconds - startOfDay.epochMilliseconds;
|
|
2820
|
+
return Math.floor(delta / 12);
|
|
2821
|
+
}
|
|
2822
|
+
/**
|
|
2823
|
+
* A method that returns sundial or solar noon. It occurs when the Sun is <a href
|
|
2824
|
+
* ="http://en.wikipedia.org/wiki/Transit_%28astronomy%29">transiting</a> the <a
|
|
2825
|
+
* href="http://en.wikipedia.org/wiki/Meridian_%28astronomy%29">celestial meridian</a>. In this class it is
|
|
2826
|
+
* calculated as halfway between the sunrise and sunset passed to this method. This time can be slightly off the
|
|
2827
|
+
* real transit time due to changes in declination (the lengthening or shortening day).
|
|
2828
|
+
*
|
|
2829
|
+
* @param {Temporal.ZonedDateTime | null} startOfDay
|
|
2830
|
+
* the start of day for calculating the sun's transit. This can be sea level sunrise, visual sunrise (or
|
|
2831
|
+
* any arbitrary start of day) passed to this method.
|
|
2832
|
+
* @param {Temporal.ZonedDateTime | null} endOfDay
|
|
2833
|
+
* the end of day for calculating the sun's transit. This can be sea level sunset, visual sunset (or any
|
|
2834
|
+
* arbitrary end of day) passed to this method.
|
|
2835
|
+
*
|
|
2836
|
+
* @return {Temporal.ZonedDateTime | null} The `Date` representing Sun's transit. If the calculation can't be computed such as in the
|
|
2837
|
+
* Arctic Circle where there is at least one day a year where the sun does not rise, and one where it does
|
|
2838
|
+
* not set, null will be returned. See detailed explanation on top of the page.
|
|
2839
|
+
*/
|
|
2840
|
+
getSunTransit(startOfDay = this.getSeaLevelSunrise(), endOfDay = this.getSeaLevelSunset()) {
|
|
2841
|
+
const temporalHour = this.getTemporalHour(startOfDay, endOfDay);
|
|
2842
|
+
return NOAACalculator.getTimeOffset(startOfDay, temporalHour * 6);
|
|
2843
|
+
}
|
|
2844
|
+
/**
|
|
2845
|
+
* A method that returns a `Date` from the time passed in as a parameter.
|
|
2846
|
+
* @protected
|
|
2847
|
+
* @param {number} time
|
|
2848
|
+
* The time to be set as the time for the `Date`. The time expected is in the format: 18.75
|
|
2849
|
+
* for 6:45:00 PM.
|
|
2850
|
+
* @param {boolean} isSunrise true if the time is sunrise, and false if it is sunset
|
|
2851
|
+
* @return {Temporal.ZonedDateTime | null} The Date.
|
|
2852
|
+
*/
|
|
2853
|
+
getDateFromTime(time, isSunrise) {
|
|
2854
|
+
if (isNaN(time)) {
|
|
2855
|
+
return null;
|
|
2856
|
+
}
|
|
2857
|
+
let calculatedTime = time;
|
|
2858
|
+
let cal = this.getAdjustedDate();
|
|
2859
|
+
// let cal = new Temporal.PlainDate(adj.year, adj.month, adj.day);
|
|
2860
|
+
const hours = Math.trunc(calculatedTime); // retain only the hours
|
|
2861
|
+
calculatedTime -= hours;
|
|
2862
|
+
const minutes = Math.trunc((calculatedTime *= 60)); // retain only the minutes
|
|
2863
|
+
calculatedTime -= minutes;
|
|
2864
|
+
const seconds = Math.trunc((calculatedTime *= 60)); // retain only the seconds
|
|
2865
|
+
calculatedTime -= seconds; // remaining milliseconds
|
|
2866
|
+
// Check if a date transition has occurred, or is about to occur - this indicates the date of the event is
|
|
2867
|
+
// actually not the target date, but the day prior or after
|
|
2868
|
+
const localTimeHours = Math.trunc(this.geoLocation.getLongitude() / 15);
|
|
2869
|
+
if (isSunrise && localTimeHours + hours > 18) {
|
|
2870
|
+
cal = cal.add({ days: -1 });
|
|
2871
|
+
// cal = cal.minus({days: 1});
|
|
2872
|
+
}
|
|
2873
|
+
else if (!isSunrise && localTimeHours + hours < 6) {
|
|
2874
|
+
cal = cal.add({ days: 1 });
|
|
2875
|
+
}
|
|
2876
|
+
return cal
|
|
2877
|
+
.toZonedDateTime({
|
|
2878
|
+
timeZone: 'UTC',
|
|
2879
|
+
plainTime: new Temporal.PlainTime(hours, minutes, seconds, Math.trunc(calculatedTime * 1000)),
|
|
2880
|
+
})
|
|
2881
|
+
.withTimeZone(this.geoLocation.getTimeZone());
|
|
2882
|
+
}
|
|
2883
|
+
/**
|
|
2884
|
+
* Return the <a href="http://en.wikipedia.org/wiki/Julian_day">Julian day</a> from a Java Calendar
|
|
2885
|
+
* @private
|
|
2886
|
+
* @param {Temporal.ZonedDateTime} date
|
|
2887
|
+
* The Java Calendar
|
|
2888
|
+
* @return the Julian day corresponding to the date Note: Number is returned for start of day. Fractional days
|
|
2889
|
+
* should be added later.
|
|
2890
|
+
*/
|
|
2891
|
+
static getJulianDay(date) {
|
|
2892
|
+
let { year, month } = date;
|
|
2893
|
+
const { day } = date;
|
|
2894
|
+
if (month <= 2) {
|
|
2895
|
+
year -= 1;
|
|
2896
|
+
month += 12;
|
|
2897
|
+
}
|
|
2898
|
+
const a = Math.trunc(year / 100);
|
|
2899
|
+
const b = Math.trunc(2 - a + a / 4);
|
|
2900
|
+
return (Math.floor(365.25 * (year + 4716)) +
|
|
2901
|
+
Math.floor(30.6001 * (month + 1)) +
|
|
2902
|
+
day +
|
|
2903
|
+
b -
|
|
2904
|
+
1524.5);
|
|
2905
|
+
}
|
|
2906
|
+
/**
|
|
2907
|
+
* Convert <a href="http://en.wikipedia.org/wiki/Julian_day">Julian day</a> to centuries since J2000.0.
|
|
2908
|
+
* @private
|
|
2909
|
+
* @param julianDay
|
|
2910
|
+
* the Julian Day to convert
|
|
2911
|
+
* @return the centuries since 2000 Julian corresponding to the Julian Day
|
|
2912
|
+
*/
|
|
2913
|
+
static getJulianCenturiesFromJulianDay(julianDay) {
|
|
2914
|
+
return ((julianDay - NOAACalculator.JULIAN_DAY_JAN_1_2000) /
|
|
2915
|
+
NOAACalculator.JULIAN_DAYS_PER_CENTURY);
|
|
2916
|
+
}
|
|
2917
|
+
/**
|
|
2918
|
+
* Convert centuries since J2000.0 to <a href="http://en.wikipedia.org/wiki/Julian_day">Julian day</a>.
|
|
2919
|
+
* @private
|
|
2920
|
+
* @param julianCenturies
|
|
2921
|
+
* the number of Julian centuries since J2000.0
|
|
2922
|
+
* @return the Julian Day corresponding to the Julian centuries passed in
|
|
2923
|
+
*/
|
|
2924
|
+
static getJulianDayFromJulianCenturies(julianCenturies) {
|
|
2925
|
+
return (julianCenturies * NOAACalculator.JULIAN_DAYS_PER_CENTURY +
|
|
2926
|
+
NOAACalculator.JULIAN_DAY_JAN_1_2000);
|
|
2927
|
+
}
|
|
2928
|
+
/**
|
|
2929
|
+
* Returns the Geometric <a href="http://en.wikipedia.org/wiki/Mean_longitude">Mean Longitude</a> of the Sun.
|
|
2930
|
+
* @private
|
|
2931
|
+
* @param julianCenturies
|
|
2932
|
+
* the number of Julian centuries since J2000.0
|
|
2933
|
+
* @return the Geometric Mean Longitude of the Sun in degrees
|
|
2934
|
+
*/
|
|
2935
|
+
static getSunGeometricMeanLongitude(julianCenturies) {
|
|
2936
|
+
let longitude = 280.46646 + julianCenturies * (36000.76983 + 0.0003032 * julianCenturies);
|
|
2937
|
+
while (longitude > 360) {
|
|
2938
|
+
longitude -= 360;
|
|
2939
|
+
}
|
|
2940
|
+
while (longitude < 0) {
|
|
2941
|
+
longitude += 360;
|
|
2942
|
+
}
|
|
2943
|
+
return longitude; // in degrees
|
|
2944
|
+
}
|
|
2945
|
+
/**
|
|
2946
|
+
* Returns the Geometric <a href="http://en.wikipedia.org/wiki/Mean_anomaly">Mean Anomaly</a> of the Sun.
|
|
2947
|
+
* @private
|
|
2948
|
+
* @param julianCenturies
|
|
2949
|
+
* the number of Julian centuries since J2000.0
|
|
2950
|
+
* @return the Geometric Mean Anomaly of the Sun in degrees
|
|
2951
|
+
*/
|
|
2952
|
+
static getSunGeometricMeanAnomaly(julianCenturies) {
|
|
2953
|
+
return (357.52911 + julianCenturies * (35999.05029 - 0.0001537 * julianCenturies)); // in degrees
|
|
2954
|
+
}
|
|
2955
|
+
/**
|
|
2956
|
+
* Return the <a href="http://en.wikipedia.org/wiki/Eccentricity_%28orbit%29">eccentricity of earth's orbit</a>.
|
|
2957
|
+
* @private
|
|
2958
|
+
* @param julianCenturies
|
|
2959
|
+
* the number of Julian centuries since J2000.0
|
|
2960
|
+
* @return the unitless eccentricity
|
|
2961
|
+
*/
|
|
2962
|
+
static getEarthOrbitEccentricity(julianCenturies) {
|
|
2963
|
+
return (0.016708634 -
|
|
2964
|
+
julianCenturies * (0.000042037 + 0.0000001267 * julianCenturies)); // unitless
|
|
2965
|
+
}
|
|
2966
|
+
/**
|
|
2967
|
+
* Returns the <a href="http://en.wikipedia.org/wiki/Equation_of_the_center">equation of center</a> for the sun.
|
|
2968
|
+
* @private
|
|
2969
|
+
* @param julianCenturies
|
|
2970
|
+
* the number of Julian centuries since J2000.0
|
|
2971
|
+
* @return the equation of center for the sun in degrees
|
|
2972
|
+
*/
|
|
2973
|
+
static getSunEquationOfCenter(julianCenturies) {
|
|
2974
|
+
const m = NOAACalculator.getSunGeometricMeanAnomaly(julianCenturies);
|
|
2975
|
+
const mrad = degreesToRadians(m);
|
|
2976
|
+
const sinm = Math.sin(mrad);
|
|
2977
|
+
const sin2m = Math.sin(mrad + mrad);
|
|
2978
|
+
const sin3m = Math.sin(mrad + mrad + mrad);
|
|
2979
|
+
return (sinm *
|
|
2980
|
+
(1.914602 - julianCenturies * (0.004817 + 0.000014 * julianCenturies)) +
|
|
2981
|
+
sin2m * (0.019993 - 0.000101 * julianCenturies) +
|
|
2982
|
+
sin3m * 0.000289); // in degrees
|
|
2983
|
+
}
|
|
2984
|
+
/**
|
|
2985
|
+
* Return the true longitude of the sun
|
|
2986
|
+
* @private
|
|
2987
|
+
* @param julianCenturies
|
|
2988
|
+
* the number of Julian centuries since J2000.0
|
|
2989
|
+
* @return the sun's true longitude in degrees
|
|
2990
|
+
*/
|
|
2991
|
+
static getSunTrueLongitude(julianCenturies) {
|
|
2992
|
+
const sunLongitude = NOAACalculator.getSunGeometricMeanLongitude(julianCenturies);
|
|
2993
|
+
const center = NOAACalculator.getSunEquationOfCenter(julianCenturies);
|
|
2994
|
+
return sunLongitude + center; // in degrees
|
|
2995
|
+
}
|
|
2996
|
+
/**
|
|
2997
|
+
* Return the apparent longitude of the sun
|
|
2998
|
+
* @private
|
|
2999
|
+
* @param julianCenturies
|
|
3000
|
+
* the number of Julian centuries since J2000.0
|
|
3001
|
+
* @return sun's apparent longitude in degrees
|
|
3002
|
+
*/
|
|
3003
|
+
static getSunApparentLongitude(julianCenturies) {
|
|
3004
|
+
const sunTrueLongitude = NOAACalculator.getSunTrueLongitude(julianCenturies);
|
|
3005
|
+
const omega = 125.04 - 1934.136 * julianCenturies;
|
|
3006
|
+
const lambda = sunTrueLongitude - 0.00569 - 0.00478 * Math.sin(degreesToRadians(omega));
|
|
3007
|
+
return lambda; // in degrees
|
|
3008
|
+
}
|
|
3009
|
+
/**
|
|
3010
|
+
* Returns the mean <a href="http://en.wikipedia.org/wiki/Axial_tilt">obliquity of the ecliptic</a> (Axial tilt).
|
|
3011
|
+
* @private
|
|
3012
|
+
* @param julianCenturies
|
|
3013
|
+
* the number of Julian centuries since J2000.0
|
|
3014
|
+
* @return the mean obliquity in degrees
|
|
3015
|
+
*/
|
|
3016
|
+
static getMeanObliquityOfEcliptic(julianCenturies) {
|
|
3017
|
+
const seconds = 21.448 -
|
|
3018
|
+
julianCenturies *
|
|
3019
|
+
(46.815 + julianCenturies * (0.00059 - julianCenturies * 0.001813));
|
|
3020
|
+
return 23 + (26 + seconds / 60) / 60; // in degrees
|
|
3021
|
+
}
|
|
3022
|
+
/**
|
|
3023
|
+
* Returns the corrected <a href="http://en.wikipedia.org/wiki/Axial_tilt">obliquity of the ecliptic</a> (Axial
|
|
3024
|
+
* tilt).
|
|
3025
|
+
* @private
|
|
3026
|
+
* @param julianCenturies
|
|
3027
|
+
* the number of Julian centuries since J2000.0
|
|
3028
|
+
* @return the corrected obliquity in degrees
|
|
3029
|
+
*/
|
|
3030
|
+
static getObliquityCorrection(julianCenturies) {
|
|
3031
|
+
const obliquityOfEcliptic = NOAACalculator.getMeanObliquityOfEcliptic(julianCenturies);
|
|
3032
|
+
const omega = 125.04 - 1934.136 * julianCenturies;
|
|
3033
|
+
return obliquityOfEcliptic + 0.00256 * Math.cos(degreesToRadians(omega)); // in degrees
|
|
3034
|
+
}
|
|
3035
|
+
/**
|
|
3036
|
+
* Return the <a href="http://en.wikipedia.org/wiki/Declination">declination</a> of the sun.
|
|
3037
|
+
* @private
|
|
3038
|
+
* @param julianCenturies
|
|
3039
|
+
* the number of Julian centuries since J2000.0
|
|
3040
|
+
* @return
|
|
3041
|
+
* the sun's declination in degrees
|
|
3042
|
+
*/
|
|
3043
|
+
static getSunDeclination(julianCenturies) {
|
|
3044
|
+
const obliquityCorrection = NOAACalculator.getObliquityCorrection(julianCenturies);
|
|
3045
|
+
const lambda = NOAACalculator.getSunApparentLongitude(julianCenturies);
|
|
3046
|
+
const sint = Math.sin(degreesToRadians(obliquityCorrection)) *
|
|
3047
|
+
Math.sin(degreesToRadians(lambda));
|
|
3048
|
+
const theta = radiansToDegrees(Math.asin(sint));
|
|
3049
|
+
return theta; // in degrees
|
|
3050
|
+
}
|
|
3051
|
+
/**
|
|
3052
|
+
* Return the <a href="http://en.wikipedia.org/wiki/Equation_of_time">Equation of Time</a> - the difference between
|
|
3053
|
+
* true solar time and mean solar time
|
|
3054
|
+
* @private
|
|
3055
|
+
* @param julianCenturies
|
|
3056
|
+
* the number of Julian centuries since J2000.0
|
|
3057
|
+
* @return equation of time in minutes of time
|
|
3058
|
+
*/
|
|
3059
|
+
static getEquationOfTime(julianCenturies) {
|
|
3060
|
+
const epsilon = NOAACalculator.getObliquityCorrection(julianCenturies);
|
|
3061
|
+
const geomMeanLongSun = NOAACalculator.getSunGeometricMeanLongitude(julianCenturies);
|
|
3062
|
+
const eccentricityEarthOrbit = NOAACalculator.getEarthOrbitEccentricity(julianCenturies);
|
|
3063
|
+
const geomMeanAnomalySun = NOAACalculator.getSunGeometricMeanAnomaly(julianCenturies);
|
|
3064
|
+
let y = Math.tan(degreesToRadians(epsilon) / 2);
|
|
3065
|
+
y *= y;
|
|
3066
|
+
const sin2l0 = Math.sin(2 * degreesToRadians(geomMeanLongSun));
|
|
3067
|
+
const sinm = Math.sin(degreesToRadians(geomMeanAnomalySun));
|
|
3068
|
+
const cos2l0 = Math.cos(2 * degreesToRadians(geomMeanLongSun));
|
|
3069
|
+
const sin4l0 = Math.sin(4 * degreesToRadians(geomMeanLongSun));
|
|
3070
|
+
const sin2m = Math.sin(2 * degreesToRadians(geomMeanAnomalySun));
|
|
3071
|
+
const equationOfTime = y * sin2l0 -
|
|
3072
|
+
2 * eccentricityEarthOrbit * sinm +
|
|
3073
|
+
4 * eccentricityEarthOrbit * y * sinm * cos2l0 -
|
|
3074
|
+
0.5 * y * y * sin4l0 -
|
|
3075
|
+
1.25 * eccentricityEarthOrbit * eccentricityEarthOrbit * sin2m;
|
|
3076
|
+
return radiansToDegrees(equationOfTime) * 4; // in minutes of time
|
|
3077
|
+
}
|
|
3078
|
+
/**
|
|
3079
|
+
* Return the <a href="http://en.wikipedia.org/wiki/Hour_angle">hour angle</a> of the sun at sunrise for the
|
|
3080
|
+
* latitude.
|
|
3081
|
+
* @private
|
|
3082
|
+
* @param {number} lat
|
|
3083
|
+
* , the latitude of observer in degrees
|
|
3084
|
+
* @param solarDec
|
|
3085
|
+
* the declination angle of sun in degrees
|
|
3086
|
+
* @param {number} zenith
|
|
3087
|
+
* the zenith
|
|
3088
|
+
* @return hour angle of sunrise in radians
|
|
3089
|
+
*/
|
|
3090
|
+
static getSunHourAngleAtSunrise(lat, solarDec, zenith) {
|
|
3091
|
+
const latRad = degreesToRadians(lat);
|
|
3092
|
+
const sdRad = degreesToRadians(solarDec);
|
|
3093
|
+
return Math.acos(Math.cos(degreesToRadians(zenith)) /
|
|
3094
|
+
(Math.cos(latRad) * Math.cos(sdRad)) -
|
|
3095
|
+
Math.tan(latRad) * Math.tan(sdRad)); // in radians
|
|
3096
|
+
}
|
|
3097
|
+
/**
|
|
3098
|
+
* Returns the <a href="http://en.wikipedia.org/wiki/Hour_angle">hour angle</a> of the sun at sunset for the
|
|
3099
|
+
* latitude.
|
|
3100
|
+
* @private
|
|
3101
|
+
* @param {number} lat
|
|
3102
|
+
* the latitude of observer in degrees
|
|
3103
|
+
* @param solarDec
|
|
3104
|
+
* the declination angle of sun in degrees
|
|
3105
|
+
* @param {number} zenith
|
|
3106
|
+
* the zenith
|
|
3107
|
+
* @return the hour angle of sunset in radians
|
|
3108
|
+
*/
|
|
3109
|
+
static getSunHourAngleAtSunset(lat, solarDec, zenith) {
|
|
3110
|
+
const latRad = degreesToRadians(lat);
|
|
3111
|
+
const sdRad = degreesToRadians(solarDec);
|
|
3112
|
+
const hourAngle = Math.acos(Math.cos(degreesToRadians(zenith)) /
|
|
3113
|
+
(Math.cos(latRad) * Math.cos(sdRad)) -
|
|
3114
|
+
Math.tan(latRad) * Math.tan(sdRad));
|
|
3115
|
+
return -hourAngle; // in radians
|
|
3116
|
+
}
|
|
3117
|
+
/**
|
|
3118
|
+
* Return the <a href="http://en.wikipedia.org/wiki/Celestial_coordinate_system">Solar Elevation</a> for the
|
|
3119
|
+
* horizontal coordinate system at the given location at the given time. Can be negative if the sun is below the
|
|
3120
|
+
* horizon. Not corrected for altitude.
|
|
3121
|
+
*
|
|
3122
|
+
* @param {Temporal.ZonedDateTime} date
|
|
3123
|
+
* time of calculation
|
|
3124
|
+
* @param {number} lat
|
|
3125
|
+
* latitude of location for calculation
|
|
3126
|
+
* @param {number} lon
|
|
3127
|
+
* longitude of location for calculation
|
|
3128
|
+
* @return {number} solar elevation in degrees - horizon is 0 degrees, civil twilight is -6 degrees
|
|
3129
|
+
*/
|
|
3130
|
+
static getSolarElevation(date, lat, lon) {
|
|
3131
|
+
const julianDay = NOAACalculator.getJulianDay(date.toPlainDate());
|
|
3132
|
+
const julianCenturies = NOAACalculator.getJulianCenturiesFromJulianDay(julianDay);
|
|
3133
|
+
const equationOfTime = NOAACalculator.getEquationOfTime(julianCenturies);
|
|
3134
|
+
let longitude = date.hour + 12 + (date.minute + equationOfTime + date.second / 60) / 60;
|
|
3135
|
+
longitude = -((longitude * 360) / 24) % 360;
|
|
3136
|
+
const hourAngleRad = degreesToRadians(lon - longitude);
|
|
3137
|
+
const declination = NOAACalculator.getSunDeclination(julianCenturies);
|
|
3138
|
+
const decRad = degreesToRadians(declination);
|
|
3139
|
+
const latRad = degreesToRadians(lat);
|
|
3140
|
+
return radiansToDegrees(Math.asin(Math.sin(latRad) * Math.sin(decRad) +
|
|
3141
|
+
Math.cos(latRad) * Math.cos(decRad) * Math.cos(hourAngleRad)));
|
|
3142
|
+
}
|
|
3143
|
+
/**
|
|
3144
|
+
* Return the <a href="http://en.wikipedia.org/wiki/Celestial_coordinate_system">Solar Azimuth</a> for the
|
|
3145
|
+
* horizontal coordinate system at the given location at the given time. Not corrected for altitude. True south is 0
|
|
3146
|
+
* degrees.
|
|
3147
|
+
*
|
|
3148
|
+
* @param {Temporal.ZonedDateTime} date
|
|
3149
|
+
* time of calculation
|
|
3150
|
+
* @param {number} latitude
|
|
3151
|
+
* latitude of location for calculation
|
|
3152
|
+
* @param {number} lon
|
|
3153
|
+
* longitude of location for calculation
|
|
3154
|
+
* @return {number}
|
|
3155
|
+
*/
|
|
3156
|
+
static getSolarAzimuth(date, latitude, lon) {
|
|
3157
|
+
const julianDay = NOAACalculator.getJulianDay(date.toPlainDate());
|
|
3158
|
+
const julianCenturies = NOAACalculator.getJulianCenturiesFromJulianDay(julianDay);
|
|
3159
|
+
const equationOfTime = NOAACalculator.getEquationOfTime(julianCenturies);
|
|
3160
|
+
let longitude = date.hour + 12 + (date.minute + equationOfTime + date.second / 60) / 60;
|
|
3161
|
+
longitude = -((longitude * 360) / 24) % 360;
|
|
3162
|
+
const hourAngleRad = degreesToRadians(lon - longitude);
|
|
3163
|
+
const declination = NOAACalculator.getSunDeclination(julianCenturies);
|
|
3164
|
+
const decRad = degreesToRadians(declination);
|
|
3165
|
+
const latRad = degreesToRadians(latitude);
|
|
3166
|
+
return (radiansToDegrees(Math.atan(Math.sin(hourAngleRad) /
|
|
3167
|
+
(Math.cos(hourAngleRad) * Math.sin(latRad) -
|
|
3168
|
+
Math.tan(decRad) * Math.cos(latRad)))) + 180);
|
|
3169
|
+
}
|
|
3170
|
+
/**
|
|
3171
|
+
* Return the <a href="http://en.wikipedia.org/wiki/Universal_Coordinated_Time">Universal Coordinated Time</a> (UTC)
|
|
3172
|
+
* of sunrise for the given day at the given location on earth
|
|
3173
|
+
* @private
|
|
3174
|
+
* @param julianDay
|
|
3175
|
+
* the Julian day
|
|
3176
|
+
* @param {number} latitude
|
|
3177
|
+
* the latitude of observer in degrees
|
|
3178
|
+
* @param {number} longitude
|
|
3179
|
+
* the longitude of observer in degrees
|
|
3180
|
+
* @param {number} zenith
|
|
3181
|
+
* the zenith
|
|
3182
|
+
* @return the time in minutes from zero UTC
|
|
3183
|
+
*/
|
|
3184
|
+
static getSunriseUTC(julianDay, latitude, longitude, zenith) {
|
|
3185
|
+
const julianCenturies = NOAACalculator.getJulianCenturiesFromJulianDay(julianDay);
|
|
3186
|
+
// Find the time of solar noon at the location, and use that declination. This is better than start of the
|
|
3187
|
+
// Julian day
|
|
3188
|
+
const noonmin = NOAACalculator.getSolarNoonUTC(julianCenturies, longitude);
|
|
3189
|
+
const tnoon = NOAACalculator.getJulianCenturiesFromJulianDay(julianDay + noonmin / 1440);
|
|
3190
|
+
// First pass to approximate sunrise (using solar noon)
|
|
3191
|
+
let eqTime = NOAACalculator.getEquationOfTime(tnoon);
|
|
3192
|
+
let solarDec = NOAACalculator.getSunDeclination(tnoon);
|
|
3193
|
+
let hourAngle = NOAACalculator.getSunHourAngleAtSunrise(latitude, solarDec, zenith);
|
|
3194
|
+
let delta = longitude - radiansToDegrees(hourAngle);
|
|
3195
|
+
let timeDiff = 4 * delta; // in minutes of time
|
|
3196
|
+
let timeUTC = 720 + timeDiff - eqTime; // in minutes
|
|
3197
|
+
// Second pass includes fractional Julian Day in gamma calc
|
|
3198
|
+
const newt = NOAACalculator.getJulianCenturiesFromJulianDay(NOAACalculator.getJulianDayFromJulianCenturies(julianCenturies) +
|
|
3199
|
+
timeUTC / 1440);
|
|
3200
|
+
eqTime = NOAACalculator.getEquationOfTime(newt);
|
|
3201
|
+
solarDec = NOAACalculator.getSunDeclination(newt);
|
|
3202
|
+
hourAngle = NOAACalculator.getSunHourAngleAtSunrise(latitude, solarDec, zenith);
|
|
3203
|
+
delta = longitude - radiansToDegrees(hourAngle);
|
|
3204
|
+
timeDiff = 4 * delta;
|
|
3205
|
+
timeUTC = 720 + timeDiff - eqTime; // in minutes
|
|
3206
|
+
return timeUTC;
|
|
3207
|
+
}
|
|
3208
|
+
/**
|
|
3209
|
+
* Return the <a href="http://en.wikipedia.org/wiki/Universal_Coordinated_Time">Universal Coordinated Time</a> (UTC)
|
|
3210
|
+
* of <a href="http://en.wikipedia.org/wiki/Noon#Solar_noon">solar noon</a> for the given day at the given location
|
|
3211
|
+
* on earth.
|
|
3212
|
+
* @private
|
|
3213
|
+
* @param julianCenturies
|
|
3214
|
+
* the number of Julian centuries since J2000.0
|
|
3215
|
+
* @param {number} longitude
|
|
3216
|
+
* the longitude of observer in degrees
|
|
3217
|
+
* @return the time in minutes from zero UTC
|
|
3218
|
+
*/
|
|
3219
|
+
static getSolarNoonUTC(julianCenturies, longitude) {
|
|
3220
|
+
// First pass uses approximate solar noon to calculate eqtime
|
|
3221
|
+
const tnoon = NOAACalculator.getJulianCenturiesFromJulianDay(NOAACalculator.getJulianDayFromJulianCenturies(julianCenturies) +
|
|
3222
|
+
longitude / 360);
|
|
3223
|
+
let eqTime = NOAACalculator.getEquationOfTime(tnoon);
|
|
3224
|
+
const solNoonUTC = 720 + longitude * 4 - eqTime; // min
|
|
3225
|
+
const newt = NOAACalculator.getJulianCenturiesFromJulianDay(NOAACalculator.getJulianDayFromJulianCenturies(julianCenturies) -
|
|
3226
|
+
0.5 +
|
|
3227
|
+
solNoonUTC / 1440);
|
|
3228
|
+
eqTime = NOAACalculator.getEquationOfTime(newt);
|
|
3229
|
+
return 720 + longitude * 4 - eqTime; // min
|
|
3230
|
+
}
|
|
3231
|
+
/**
|
|
3232
|
+
* Return the <a href="http://en.wikipedia.org/wiki/Universal_Coordinated_Time">Universal Coordinated Time</a> (UTC)
|
|
3233
|
+
* of sunset for the given day at the given location on earth
|
|
3234
|
+
* @private
|
|
3235
|
+
* @param julianDay
|
|
3236
|
+
* the Julian day
|
|
3237
|
+
* @param {number} latitude
|
|
3238
|
+
* the latitude of observer in degrees
|
|
3239
|
+
* @param {number} longitude
|
|
3240
|
+
* : longitude of observer in degrees
|
|
3241
|
+
* @param {number} zenith
|
|
3242
|
+
* the zenith
|
|
3243
|
+
* @return the time in minutes from zero Universal Coordinated Time (UTC)
|
|
3244
|
+
*/
|
|
3245
|
+
static getSunsetUTC(julianDay, latitude, longitude, zenith) {
|
|
3246
|
+
const julianCenturies = NOAACalculator.getJulianCenturiesFromJulianDay(julianDay);
|
|
3247
|
+
// Find the time of solar noon at the location, and use that declination. This is better than start of the
|
|
3248
|
+
// Julian day
|
|
3249
|
+
const noonmin = NOAACalculator.getSolarNoonUTC(julianCenturies, longitude);
|
|
3250
|
+
const tnoon = NOAACalculator.getJulianCenturiesFromJulianDay(julianDay + noonmin / 1440);
|
|
3251
|
+
// First calculates sunrise and approx length of day
|
|
3252
|
+
let eqTime = NOAACalculator.getEquationOfTime(tnoon);
|
|
3253
|
+
let solarDec = NOAACalculator.getSunDeclination(tnoon);
|
|
3254
|
+
let hourAngle = NOAACalculator.getSunHourAngleAtSunset(latitude, solarDec, zenith);
|
|
3255
|
+
let delta = longitude - radiansToDegrees(hourAngle);
|
|
3256
|
+
let timeDiff = 4 * delta;
|
|
3257
|
+
let timeUTC = 720 + timeDiff - eqTime;
|
|
3258
|
+
// Second pass includes fractional Julian Day in gamma calc
|
|
3259
|
+
const newt = NOAACalculator.getJulianCenturiesFromJulianDay(NOAACalculator.getJulianDayFromJulianCenturies(julianCenturies) +
|
|
3260
|
+
timeUTC / 1440);
|
|
3261
|
+
eqTime = NOAACalculator.getEquationOfTime(newt);
|
|
3262
|
+
solarDec = NOAACalculator.getSunDeclination(newt);
|
|
3263
|
+
hourAngle = NOAACalculator.getSunHourAngleAtSunset(latitude, solarDec, zenith);
|
|
3264
|
+
delta = longitude - radiansToDegrees(hourAngle);
|
|
3265
|
+
timeDiff = 4 * delta;
|
|
3266
|
+
timeUTC = 720 + timeDiff - eqTime; // in minutes
|
|
3267
|
+
return timeUTC;
|
|
3268
|
+
}
|
|
3269
|
+
}
|
|
3270
|
+
/**
|
|
3271
|
+
* The zenith of astronomical sunrise and sunset. The sun is 90° from the vertical 0°
|
|
3272
|
+
* @private
|
|
3273
|
+
*/
|
|
3274
|
+
NOAACalculator.GEOMETRIC_ZENITH = 90;
|
|
3275
|
+
/**
|
|
3276
|
+
* Default value for Sun's zenith and true rise/set Zenith (used in this class and subclasses) is the angle that the
|
|
3277
|
+
* center of the Sun makes to a line perpendicular to the Earth's surface. If the Sun were a point and the Earth
|
|
3278
|
+
* were without an atmosphere, true sunset and sunrise would correspond to a 90° zenith. Because the Sun is not
|
|
3279
|
+
* a point, and because the atmosphere refracts light, this 90° zenith does not, in fact, correspond to true
|
|
3280
|
+
* sunset or sunrise, instead the center of the Sun's disk must lie just below the horizon for the upper edge to be
|
|
3281
|
+
* obscured. This means that a zenith of just above 90° must be used. The Sun subtends an angle of 16 minutes of
|
|
3282
|
+
* arc, and atmospheric refraction accounts for
|
|
3283
|
+
* 34 minutes or so, giving a total of 50
|
|
3284
|
+
* arcminutes. The total value for ZENITH is 90+(5/6) or 90.8333333° for true sunrise/sunset.
|
|
3285
|
+
*/
|
|
3286
|
+
// const ZENITH: number = GEOMETRIC_ZENITH + 5.0 / 6.0;
|
|
3287
|
+
/** Sun's zenith at civil twilight (96°). */
|
|
3288
|
+
NOAACalculator.CIVIL_ZENITH = 96;
|
|
3289
|
+
/** Sun's zenith at nautical twilight (102°). */
|
|
3290
|
+
NOAACalculator.NAUTICAL_ZENITH = 102;
|
|
3291
|
+
/** Sun's zenith at astronomical twilight (108°). */
|
|
3292
|
+
NOAACalculator.ASTRONOMICAL_ZENITH = 108;
|
|
3293
|
+
/**
|
|
3294
|
+
* The <a href="http://en.wikipedia.org/wiki/Julian_day">Julian day</a> of January 1, 2000
|
|
3295
|
+
* @private
|
|
3296
|
+
*/
|
|
3297
|
+
NOAACalculator.JULIAN_DAY_JAN_1_2000 = 2451545;
|
|
3298
|
+
/**
|
|
3299
|
+
* Julian days per century
|
|
3300
|
+
* @private
|
|
3301
|
+
*/
|
|
3302
|
+
NOAACalculator.JULIAN_DAYS_PER_CENTURY = 36525;
|
|
3303
|
+
|
|
337
3304
|
/*
|
|
338
3305
|
Hebcal - A Jewish Calendar Generator
|
|
339
3306
|
Copyright (c) 1994-2020 Danny Sadinoff
|
|
@@ -466,7 +3433,7 @@ function getFormatter(tzid) {
|
|
|
466
3433
|
return f;
|
|
467
3434
|
}
|
|
468
3435
|
/** Class representing Location */
|
|
469
|
-
class Location extends
|
|
3436
|
+
class Location extends GeoLocation {
|
|
470
3437
|
/**
|
|
471
3438
|
* Initialize a Location instance
|
|
472
3439
|
* @param latitude - Latitude as a decimal, valid range -90 thru +90 (e.g. 41.85003)
|
|
@@ -650,9 +3617,9 @@ function zdtToDate(zdt) {
|
|
|
650
3617
|
return res;
|
|
651
3618
|
}
|
|
652
3619
|
function getDate(date) {
|
|
653
|
-
if (
|
|
3620
|
+
if (isDate(date))
|
|
654
3621
|
return date;
|
|
655
|
-
if (
|
|
3622
|
+
if (HDate.isHDate(date))
|
|
656
3623
|
return date.greg();
|
|
657
3624
|
throw new TypeError(`invalid date: ${date}`);
|
|
658
3625
|
}
|
|
@@ -703,7 +3670,7 @@ class Zmanim {
|
|
|
703
3670
|
month: dt.getMonth() + 1,
|
|
704
3671
|
day: dt.getDate(),
|
|
705
3672
|
});
|
|
706
|
-
this.noaa = new
|
|
3673
|
+
this.noaa = new NOAACalculator(gloc, plainDate);
|
|
707
3674
|
this.useElevation = Boolean(useElevation);
|
|
708
3675
|
}
|
|
709
3676
|
/**
|
|
@@ -858,7 +3825,7 @@ class Zmanim {
|
|
|
858
3825
|
: this.noaa.getSeaLevelSunset();
|
|
859
3826
|
const temporalHour = this.noaa.getTemporalHour(startOfDay, endOfDay);
|
|
860
3827
|
const offset = Math.round(temporalHour * hours);
|
|
861
|
-
const zdt =
|
|
3828
|
+
const zdt = NOAACalculator.getTimeOffset(startOfDay, offset);
|
|
862
3829
|
return zdtToDate(zdt);
|
|
863
3830
|
}
|
|
864
3831
|
/**
|
|
@@ -1106,11 +4073,11 @@ class Zmanim {
|
|
|
1106
4073
|
* @param date
|
|
1107
4074
|
*/
|
|
1108
4075
|
static timeZoneOffset(tzid, date) {
|
|
1109
|
-
const offset =
|
|
4076
|
+
const offset = getTimezoneOffset(tzid, date);
|
|
1110
4077
|
const offsetAbs = Math.abs(offset);
|
|
1111
4078
|
const hours = Math.floor(offsetAbs / 60);
|
|
1112
4079
|
const minutes = offsetAbs % 60;
|
|
1113
|
-
return (offset < 0 ? '+' : '-') +
|
|
4080
|
+
return (offset < 0 ? '+' : '-') + pad2(hours) + ':' + pad2(minutes);
|
|
1114
4081
|
}
|
|
1115
4082
|
/**
|
|
1116
4083
|
* Returns a string like "2022-04-01T13:06:00-11:00"
|
|
@@ -1121,7 +4088,7 @@ class Zmanim {
|
|
|
1121
4088
|
if (isNaN(date.getTime())) {
|
|
1122
4089
|
return '0000-00-00T00:00:00Z';
|
|
1123
4090
|
}
|
|
1124
|
-
return (
|
|
4091
|
+
return (getPseudoISO(tzid, date).substring(0, 19) +
|
|
1125
4092
|
Zmanim.timeZoneOffset(tzid, date));
|
|
1126
4093
|
}
|
|
1127
4094
|
/**
|
|
@@ -1192,7 +4159,7 @@ class Zmanim {
|
|
|
1192
4159
|
static makeSunsetAwareHDate(gloc, date, useElevation) {
|
|
1193
4160
|
const zmanim = new Zmanim(gloc, date, useElevation);
|
|
1194
4161
|
const sunset = zmanim.sunset();
|
|
1195
|
-
let hd = new
|
|
4162
|
+
let hd = new HDate(date);
|
|
1196
4163
|
const sunsetMillis = sunset.getTime();
|
|
1197
4164
|
if (isNaN(sunsetMillis)) {
|
|
1198
4165
|
return hd;
|
|
@@ -1274,14 +4241,14 @@ class TimedEvent extends Event {
|
|
|
1274
4241
|
* @param [locale] Optional locale name (defaults to active locale).
|
|
1275
4242
|
*/
|
|
1276
4243
|
render(locale) {
|
|
1277
|
-
return
|
|
4244
|
+
return Locale.gettext(this.getDesc(), locale) + ': ' + this.fmtTime;
|
|
1278
4245
|
}
|
|
1279
4246
|
/**
|
|
1280
4247
|
* Returns translation of "Candle lighting" without the time.
|
|
1281
4248
|
* @param [locale] Optional locale name (defaults to active locale).
|
|
1282
4249
|
*/
|
|
1283
4250
|
renderBrief(locale) {
|
|
1284
|
-
return
|
|
4251
|
+
return Locale.gettext(this.getDesc(), locale);
|
|
1285
4252
|
}
|
|
1286
4253
|
getCategories() {
|
|
1287
4254
|
const desc = this.getDesc();
|
|
@@ -1329,9 +4296,9 @@ class HavdalahEvent extends TimedEvent {
|
|
|
1329
4296
|
* @param [locale] Optional locale name (defaults to active locale).
|
|
1330
4297
|
*/
|
|
1331
4298
|
renderBrief(locale) {
|
|
1332
|
-
let str =
|
|
4299
|
+
let str = Locale.gettext(this.getDesc(), locale);
|
|
1333
4300
|
if (this.havdalahMins) {
|
|
1334
|
-
const min =
|
|
4301
|
+
const min = Locale.gettext('min', locale);
|
|
1335
4302
|
str += ` (${this.havdalahMins} ${min})`;
|
|
1336
4303
|
}
|
|
1337
4304
|
return str;
|
|
@@ -1341,17 +4308,17 @@ class HavdalahEvent extends TimedEvent {
|
|
|
1341
4308
|
}
|
|
1342
4309
|
}
|
|
1343
4310
|
|
|
1344
|
-
const Nisan =
|
|
1345
|
-
const Iyyar =
|
|
1346
|
-
const Sivan =
|
|
1347
|
-
const Tamuz =
|
|
1348
|
-
const Av =
|
|
1349
|
-
const Elul =
|
|
1350
|
-
const Tishrei =
|
|
1351
|
-
const Cheshvan =
|
|
1352
|
-
const Kislev =
|
|
1353
|
-
const Shvat =
|
|
1354
|
-
const Adar2 =
|
|
4311
|
+
const Nisan = months.NISAN;
|
|
4312
|
+
const Iyyar = months.IYYAR;
|
|
4313
|
+
const Sivan = months.SIVAN;
|
|
4314
|
+
const Tamuz = months.TAMUZ;
|
|
4315
|
+
const Av = months.AV;
|
|
4316
|
+
const Elul = months.ELUL;
|
|
4317
|
+
const Tishrei = months.TISHREI;
|
|
4318
|
+
const Cheshvan = months.CHESHVAN;
|
|
4319
|
+
const Kislev = months.KISLEV;
|
|
4320
|
+
const Shvat = months.SHVAT;
|
|
4321
|
+
const Adar2 = months.ADAR_II;
|
|
1355
4322
|
const CHAG$1 = flags.CHAG;
|
|
1356
4323
|
const LIGHT_CANDLES$2 = flags.LIGHT_CANDLES;
|
|
1357
4324
|
const YOM_TOV_ENDS$1 = flags.YOM_TOV_ENDS;
|
|
@@ -1955,7 +4922,7 @@ const staticModernHolidays = [
|
|
|
1955
4922
|
// https://www.gov.il/he/departments/policies/2012_des5234
|
|
1956
4923
|
{
|
|
1957
4924
|
firstYear: 5773,
|
|
1958
|
-
mm:
|
|
4925
|
+
mm: months.TEVET,
|
|
1959
4926
|
dd: 21,
|
|
1960
4927
|
desc: HEBREW_LANGUAGE_DAY,
|
|
1961
4928
|
friSatMovetoThu: true,
|
|
@@ -2060,7 +5027,7 @@ class HolidayEvent extends Event {
|
|
|
2060
5027
|
*/
|
|
2061
5028
|
class AsaraBTevetEvent extends HolidayEvent {
|
|
2062
5029
|
urlDateSuffix() {
|
|
2063
|
-
const isoDate =
|
|
5030
|
+
const isoDate = isoDateString(this.getDate().greg());
|
|
2064
5031
|
return isoDate.replace(/-/g, '');
|
|
2065
5032
|
}
|
|
2066
5033
|
}
|
|
@@ -2095,7 +5062,7 @@ class RoshHashanaEvent extends HolidayEvent {
|
|
|
2095
5062
|
* @param [locale] Optional locale name (defaults to active locale).
|
|
2096
5063
|
*/
|
|
2097
5064
|
render(locale) {
|
|
2098
|
-
return
|
|
5065
|
+
return Locale.gettext('Rosh Hashana', locale) + ' ' + this.hyear;
|
|
2099
5066
|
}
|
|
2100
5067
|
getEmoji() {
|
|
2101
5068
|
return '🍏🍯';
|
|
@@ -2118,9 +5085,9 @@ class RoshChodeshEvent extends HolidayEvent {
|
|
|
2118
5085
|
*/
|
|
2119
5086
|
render(locale) {
|
|
2120
5087
|
const monthName = this.getDesc().substring(roshChodeshStr.length + 1);
|
|
2121
|
-
const monthName0 =
|
|
5088
|
+
const monthName0 = Locale.gettext(monthName, locale);
|
|
2122
5089
|
const monthName1 = monthName0.replace(/'/g, '’');
|
|
2123
|
-
return
|
|
5090
|
+
return Locale.gettext(roshChodeshStr, locale) + ' ' + monthName1;
|
|
2124
5091
|
}
|
|
2125
5092
|
basename() {
|
|
2126
5093
|
return this.getDesc();
|
|
@@ -2241,7 +5208,7 @@ function makeFastStartEnd(ev, options) {
|
|
|
2241
5208
|
startEvent = makeTimedEvent(ev, dawn, FAST_BEGINS, options);
|
|
2242
5209
|
}
|
|
2243
5210
|
if (dt.getDay() !== 5 &&
|
|
2244
|
-
!(hd.getDate() === 14 && hd.getMonth() ===
|
|
5211
|
+
!(hd.getDate() === 14 && hd.getMonth() === months.NISAN)) {
|
|
2245
5212
|
const tzeit = zmanim.tzeit(fastEndDeg);
|
|
2246
5213
|
if (!isNaN(tzeit.getTime())) {
|
|
2247
5214
|
endEvent = makeTimedEvent(ev, tzeit, FAST_ENDS, options);
|
|
@@ -2324,7 +5291,7 @@ class Molad {
|
|
|
2324
5291
|
* @param month
|
|
2325
5292
|
*/
|
|
2326
5293
|
constructor(year, month) {
|
|
2327
|
-
this.m =
|
|
5294
|
+
this.m = molad(year, month);
|
|
2328
5295
|
}
|
|
2329
5296
|
/**
|
|
2330
5297
|
*/
|
|
@@ -2339,7 +5306,7 @@ class Molad {
|
|
|
2339
5306
|
/**
|
|
2340
5307
|
*/
|
|
2341
5308
|
getMonthName() {
|
|
2342
|
-
return
|
|
5309
|
+
return HDate.getMonthName(this.m.month, this.m.year);
|
|
2343
5310
|
}
|
|
2344
5311
|
/**
|
|
2345
5312
|
* @returns Day of Week (0=Sunday, 6=Saturday)
|
|
@@ -2371,23 +5338,23 @@ class Molad {
|
|
|
2371
5338
|
*/
|
|
2372
5339
|
render(locale, options) {
|
|
2373
5340
|
var _a;
|
|
2374
|
-
locale = locale !== null && locale !== void 0 ? locale :
|
|
5341
|
+
locale = locale !== null && locale !== void 0 ? locale : Locale.getLocaleName();
|
|
2375
5342
|
if (typeof locale === 'string') {
|
|
2376
5343
|
locale = locale.toLowerCase();
|
|
2377
5344
|
}
|
|
2378
5345
|
const isHebrewLocale = locale === 'he' || locale === 'he-x-nonikud' || locale === 'h';
|
|
2379
5346
|
const isFrenchLocale = locale === 'fr';
|
|
2380
|
-
const monthName =
|
|
5347
|
+
const monthName = Locale.gettext(this.getMonthName(), locale);
|
|
2381
5348
|
const dayNames = isHebrewLocale ? heDayNames : (isFrenchLocale ? frDayNames : shortDayNames);
|
|
2382
5349
|
const dow = dayNames[this.getDow()];
|
|
2383
5350
|
const minutes = this.getMinutes();
|
|
2384
5351
|
const hour = this.getHour();
|
|
2385
5352
|
const chalakim = this.getChalakim();
|
|
2386
|
-
const moladStr =
|
|
2387
|
-
const minutesStr = (_a =
|
|
2388
|
-
const chalakimStr =
|
|
2389
|
-
const and =
|
|
2390
|
-
const after =
|
|
5353
|
+
const moladStr = Locale.gettext('Molad', locale);
|
|
5354
|
+
const minutesStr = (_a = Locale.lookupTranslation('min', locale)) !== null && _a !== void 0 ? _a : 'minutes';
|
|
5355
|
+
const chalakimStr = Locale.gettext('chalakim', locale);
|
|
5356
|
+
const and = Locale.gettext('and', locale);
|
|
5357
|
+
const after = Locale.gettext('after', locale);
|
|
2391
5358
|
if (isHebrewLocale) {
|
|
2392
5359
|
const ampm = getHebrewTimeOfDay(hour);
|
|
2393
5360
|
const result = `${moladStr} ${monthName} יִהְיֶה בַּיּוֹם ${dow} בשָׁבוּעַ, ` +
|
|
@@ -2395,7 +5362,7 @@ class Molad {
|
|
|
2395
5362
|
`ו-${minutes} ${minutesStr} ` +
|
|
2396
5363
|
`ו-${chalakim} ${chalakimStr}`;
|
|
2397
5364
|
if (locale === 'he-x-nonikud') {
|
|
2398
|
-
return
|
|
5365
|
+
return Locale.hebrewStripNikkud(result);
|
|
2399
5366
|
}
|
|
2400
5367
|
return result;
|
|
2401
5368
|
}
|
|
@@ -2651,23 +5618,23 @@ class OmerEvent extends Event {
|
|
|
2651
5618
|
* @param [locale] Optional locale name (defaults to active locale).
|
|
2652
5619
|
*/
|
|
2653
5620
|
render(locale) {
|
|
2654
|
-
locale = locale !== null && locale !== void 0 ? locale :
|
|
5621
|
+
locale = locale !== null && locale !== void 0 ? locale : Locale.getLocaleName();
|
|
2655
5622
|
if (typeof locale === 'string') {
|
|
2656
5623
|
locale = locale.toLowerCase();
|
|
2657
5624
|
}
|
|
2658
5625
|
const isHebrewLocale = locale === 'he' || locale === 'he-x-nonikud' || locale === 'h';
|
|
2659
5626
|
const omer = this.omer;
|
|
2660
|
-
const nth = isHebrewLocale ?
|
|
2661
|
-
return nth + ' ' +
|
|
5627
|
+
const nth = isHebrewLocale ? gematriya(omer) : Locale.ordinal(omer, locale);
|
|
5628
|
+
return nth + ' ' + Locale.gettext('day of the Omer', locale);
|
|
2662
5629
|
}
|
|
2663
5630
|
/**
|
|
2664
5631
|
* Returns translation of "Omer day 22" without ordinal numbers.
|
|
2665
5632
|
* @param [locale] Optional locale name (defaults to active locale).
|
|
2666
5633
|
*/
|
|
2667
5634
|
renderBrief(locale) {
|
|
2668
|
-
return (
|
|
5635
|
+
return (Locale.gettext('Omer', locale) +
|
|
2669
5636
|
' ' +
|
|
2670
|
-
|
|
5637
|
+
Locale.gettext('day', locale) +
|
|
2671
5638
|
' ' +
|
|
2672
5639
|
this.omer);
|
|
2673
5640
|
}
|
|
@@ -2708,14 +5675,14 @@ class OmerEvent extends Event {
|
|
|
2708
5675
|
* or `הַיוֹם עֲשָׂרָה יָמִים, שְׁהֵם שָׁבוּעַ אֶחָד וְשְׁלוֹשָׁה יָמִים לָעוֹמֶר`
|
|
2709
5676
|
*/
|
|
2710
5677
|
getTodayIs(locale) {
|
|
2711
|
-
locale = locale !== null && locale !== void 0 ? locale :
|
|
5678
|
+
locale = locale !== null && locale !== void 0 ? locale : Locale.getLocaleName();
|
|
2712
5679
|
if (typeof locale === 'string') {
|
|
2713
5680
|
locale = locale.toLowerCase();
|
|
2714
5681
|
}
|
|
2715
5682
|
const isHebrew = locale === 'he' || locale === 'he-x-nonikud';
|
|
2716
5683
|
const str = isHebrew ? omerTodayIsHe(this.omer) : omerTodayIsEn(this.omer);
|
|
2717
5684
|
if (locale === 'he-x-nonikud') {
|
|
2718
|
-
return
|
|
5685
|
+
return Locale.hebrewStripNikkud(str);
|
|
2719
5686
|
}
|
|
2720
5687
|
return str;
|
|
2721
5688
|
}
|
|
@@ -2726,14 +5693,14 @@ class OmerEvent extends Event {
|
|
|
2726
5693
|
|
|
2727
5694
|
/** @private */
|
|
2728
5695
|
function renderParshaName(parsha, locale) {
|
|
2729
|
-
const locale0 = locale !== null && locale !== void 0 ? locale :
|
|
2730
|
-
let name =
|
|
5696
|
+
const locale0 = locale !== null && locale !== void 0 ? locale : Locale.getLocaleName();
|
|
5697
|
+
let name = Locale.gettext(parsha[0], locale0);
|
|
2731
5698
|
if (parsha.length === 2) {
|
|
2732
5699
|
const hyphen = locale0 === 'he' ? '־' : '-';
|
|
2733
|
-
name += hyphen +
|
|
5700
|
+
name += hyphen + Locale.gettext(parsha[1], locale0);
|
|
2734
5701
|
}
|
|
2735
5702
|
name = name.replace(/'/g, '’');
|
|
2736
|
-
const str =
|
|
5703
|
+
const str = Locale.gettext('Parashat', locale) + ' ' + name;
|
|
2737
5704
|
return str.normalize();
|
|
2738
5705
|
}
|
|
2739
5706
|
|
|
@@ -3056,8 +6023,8 @@ const INCOMPLETE = 0;
|
|
|
3056
6023
|
const REGULAR = 1;
|
|
3057
6024
|
const COMPLETE = 2;
|
|
3058
6025
|
function yearType(hyear) {
|
|
3059
|
-
const longC =
|
|
3060
|
-
const shortK =
|
|
6026
|
+
const longC = HDate.longCheshvan(hyear);
|
|
6027
|
+
const shortK = HDate.shortKislev(hyear);
|
|
3061
6028
|
if (longC && !shortK) {
|
|
3062
6029
|
return COMPLETE;
|
|
3063
6030
|
}
|
|
@@ -3080,12 +6047,12 @@ class Sedra {
|
|
|
3080
6047
|
constructor(hyear, il) {
|
|
3081
6048
|
hyear = +hyear;
|
|
3082
6049
|
this.year = hyear;
|
|
3083
|
-
const rh0 = new
|
|
6050
|
+
const rh0 = new HDate(1, months.TISHREI, hyear);
|
|
3084
6051
|
const rh = rh0.abs();
|
|
3085
6052
|
const rhDay = rh0.getDay() + 1;
|
|
3086
6053
|
// find the first Saturday on or after Rosh Hashana
|
|
3087
|
-
this.firstSaturday =
|
|
3088
|
-
const leap = +
|
|
6054
|
+
this.firstSaturday = HDate.dayOnOrBefore(6, rh + 6);
|
|
6055
|
+
const leap = +HDate.isLeapYear(hyear);
|
|
3089
6056
|
this.il = Boolean(il);
|
|
3090
6057
|
const type = yearType(hyear);
|
|
3091
6058
|
let key = `${leap}${rhDay}${type}`;
|
|
@@ -3188,7 +6155,7 @@ class Sedra {
|
|
|
3188
6155
|
if (idx === -1) {
|
|
3189
6156
|
return null; // doesn't occur this year
|
|
3190
6157
|
}
|
|
3191
|
-
return new
|
|
6158
|
+
return new HDate(this.firstSaturday + idx * 7);
|
|
3192
6159
|
}
|
|
3193
6160
|
/**
|
|
3194
6161
|
* Returns the date that a parsha (or its doubled or undoubled counterpart)
|
|
@@ -3255,32 +6222,32 @@ class Sedra {
|
|
|
3255
6222
|
* @param hd Hebrew date or R.D. days
|
|
3256
6223
|
*/
|
|
3257
6224
|
lookup(hd) {
|
|
3258
|
-
const abs = typeof hd === 'number' ? hd :
|
|
6225
|
+
const abs = typeof hd === 'number' ? hd : HDate.isHDate(hd) ? hd.abs() : NaN;
|
|
3259
6226
|
if (isNaN(abs)) {
|
|
3260
6227
|
throw new TypeError(`Bad date argument: ${hd}`);
|
|
3261
6228
|
}
|
|
3262
6229
|
// find the first saturday on or after today's date
|
|
3263
|
-
const saturday =
|
|
6230
|
+
const saturday = HDate.dayOnOrBefore(6, abs + 6);
|
|
3264
6231
|
const weekNum = (saturday - this.firstSaturday) / 7;
|
|
3265
6232
|
const index = this.theSedraArray[weekNum];
|
|
3266
6233
|
if (typeof index === 'undefined') {
|
|
3267
6234
|
const sedra = getSedra(this.year + 1, this.il);
|
|
3268
6235
|
return sedra.lookup(saturday); // must be next year
|
|
3269
6236
|
}
|
|
3270
|
-
const hdate
|
|
6237
|
+
const hdate = new HDate(saturday);
|
|
3271
6238
|
if (typeof index === 'string') {
|
|
3272
6239
|
// Shabbat has a chag. Return a description
|
|
3273
|
-
return { parsha: [index], chag: true, hdate
|
|
6240
|
+
return { parsha: [index], chag: true, hdate };
|
|
3274
6241
|
}
|
|
3275
6242
|
if (index >= 0) {
|
|
3276
|
-
return { parsha: [parshiot[index]], chag: false, num: index + 1, hdate
|
|
6243
|
+
return { parsha: [parshiot[index]], chag: false, num: index + 1, hdate };
|
|
3277
6244
|
}
|
|
3278
6245
|
const p1 = D(index); // undouble the parsha
|
|
3279
6246
|
return {
|
|
3280
6247
|
parsha: [parshiot[p1], parshiot[p1 + 1]],
|
|
3281
6248
|
chag: false,
|
|
3282
6249
|
num: [p1 + 1, p1 + 2],
|
|
3283
|
-
hdate
|
|
6250
|
+
hdate,
|
|
3284
6251
|
};
|
|
3285
6252
|
}
|
|
3286
6253
|
}
|
|
@@ -3549,7 +6516,7 @@ class ParshaEvent extends Event {
|
|
|
3549
6516
|
return this.il ? url + '?i=on' : url;
|
|
3550
6517
|
}
|
|
3551
6518
|
urlDateSuffix() {
|
|
3552
|
-
const isoDate =
|
|
6519
|
+
const isoDate = isoDateString(this.getDate().greg());
|
|
3553
6520
|
return isoDate.replace(/-/g, '');
|
|
3554
6521
|
}
|
|
3555
6522
|
}
|
|
@@ -3564,7 +6531,7 @@ class ParshaEvent extends Event {
|
|
|
3564
6531
|
function parshaYear(year, il) {
|
|
3565
6532
|
const sedra = getSedra(year, il);
|
|
3566
6533
|
const startAbs = sedra.getFirstSaturday();
|
|
3567
|
-
const endAbs =
|
|
6534
|
+
const endAbs = HDate.hebrew2abs(year, months.ELUL, 29);
|
|
3568
6535
|
const events = [];
|
|
3569
6536
|
for (let absDt = startAbs; absDt <= endAbs; absDt += 7) {
|
|
3570
6537
|
const parsha = sedra.lookup(absDt);
|
|
@@ -3580,8 +6547,8 @@ const SUN$1 = 0;
|
|
|
3580
6547
|
const TUE$1 = 2;
|
|
3581
6548
|
const FRI$2 = 5;
|
|
3582
6549
|
const SAT$2 = 6;
|
|
3583
|
-
const NISAN$2 =
|
|
3584
|
-
const IYYAR =
|
|
6550
|
+
const NISAN$2 = months.NISAN;
|
|
6551
|
+
const IYYAR = months.IYYAR;
|
|
3585
6552
|
/**
|
|
3586
6553
|
* Yom HaShoah first observed in 1951.
|
|
3587
6554
|
* When the actual date of Yom Hashoah falls on a Friday, the
|
|
@@ -3596,12 +6563,12 @@ function dateYomHaShoah(year) {
|
|
|
3596
6563
|
if (year < 5711) {
|
|
3597
6564
|
return null;
|
|
3598
6565
|
}
|
|
3599
|
-
let nisan27dt = new
|
|
6566
|
+
let nisan27dt = new HDate(27, NISAN$2, year);
|
|
3600
6567
|
if (nisan27dt.getDay() === FRI$2) {
|
|
3601
|
-
nisan27dt = new
|
|
6568
|
+
nisan27dt = new HDate(26, NISAN$2, year);
|
|
3602
6569
|
}
|
|
3603
6570
|
else if (nisan27dt.getDay() === SUN$1) {
|
|
3604
|
-
nisan27dt = new
|
|
6571
|
+
nisan27dt = new HDate(28, NISAN$2, year);
|
|
3605
6572
|
}
|
|
3606
6573
|
return nisan27dt;
|
|
3607
6574
|
}
|
|
@@ -3615,7 +6582,7 @@ function dateYomHaZikaron(year) {
|
|
|
3615
6582
|
return null;
|
|
3616
6583
|
}
|
|
3617
6584
|
let day;
|
|
3618
|
-
const pesach = new
|
|
6585
|
+
const pesach = new HDate(15, NISAN$2, year);
|
|
3619
6586
|
const pdow = pesach.getDay();
|
|
3620
6587
|
if (pdow === SUN$1) {
|
|
3621
6588
|
day = 2;
|
|
@@ -3632,7 +6599,7 @@ function dateYomHaZikaron(year) {
|
|
|
3632
6599
|
else {
|
|
3633
6600
|
day = 4;
|
|
3634
6601
|
}
|
|
3635
|
-
return new
|
|
6602
|
+
return new HDate(day, IYYAR, year);
|
|
3636
6603
|
}
|
|
3637
6604
|
|
|
3638
6605
|
const ykk = 'Yom Kippur Katan';
|
|
@@ -3655,15 +6622,15 @@ class YomKippurKatanEvent extends HolidayEvent {
|
|
|
3655
6622
|
* @param [locale] Optional locale name (defaults to active locale).
|
|
3656
6623
|
*/
|
|
3657
6624
|
render(locale) {
|
|
3658
|
-
const monthName0 =
|
|
6625
|
+
const monthName0 = Locale.gettext(this.nextMonthName, locale);
|
|
3659
6626
|
const monthName = monthName0.replace(/'/g, '’');
|
|
3660
|
-
return
|
|
6627
|
+
return Locale.gettext(ykk, locale) + ' ' + monthName;
|
|
3661
6628
|
}
|
|
3662
6629
|
/**
|
|
3663
6630
|
* @param [locale] Optional locale name (defaults to active locale).
|
|
3664
6631
|
*/
|
|
3665
6632
|
renderBrief(locale) {
|
|
3666
|
-
return
|
|
6633
|
+
return Locale.gettext(ykk, locale);
|
|
3667
6634
|
}
|
|
3668
6635
|
url() {
|
|
3669
6636
|
return undefined;
|
|
@@ -3708,7 +6675,7 @@ function holidayFilter(il) {
|
|
|
3708
6675
|
* @param [il] use the Israeli schedule for holidays
|
|
3709
6676
|
*/
|
|
3710
6677
|
function getHolidaysOnDate(date, il) {
|
|
3711
|
-
const hd =
|
|
6678
|
+
const hd = HDate.isHDate(date) ? date : new HDate(date);
|
|
3712
6679
|
const hdStr = hd.toString();
|
|
3713
6680
|
const yearMap = getHolidaysForYear_(hd.getFullYear());
|
|
3714
6681
|
const events = yearMap.get(hdStr);
|
|
@@ -3734,14 +6701,14 @@ const TUE = 2;
|
|
|
3734
6701
|
const THU = 4;
|
|
3735
6702
|
const FRI$1 = 5;
|
|
3736
6703
|
const SAT$1 = 6;
|
|
3737
|
-
const NISAN$1 =
|
|
3738
|
-
const TAMUZ =
|
|
3739
|
-
const AV =
|
|
3740
|
-
const TISHREI$1 =
|
|
3741
|
-
const KISLEV =
|
|
3742
|
-
const TEVET =
|
|
3743
|
-
const ADAR_I =
|
|
3744
|
-
const ADAR_II =
|
|
6704
|
+
const NISAN$1 = months.NISAN;
|
|
6705
|
+
const TAMUZ = months.TAMUZ;
|
|
6706
|
+
const AV = months.AV;
|
|
6707
|
+
const TISHREI$1 = months.TISHREI;
|
|
6708
|
+
const KISLEV = months.KISLEV;
|
|
6709
|
+
const TEVET = months.TEVET;
|
|
6710
|
+
const ADAR_I = months.ADAR_I;
|
|
6711
|
+
const ADAR_II = months.ADAR_II;
|
|
3745
6712
|
const emojiIsraelFlag = { emoji: '🇮🇱' };
|
|
3746
6713
|
const chanukahEmoji = '🕎';
|
|
3747
6714
|
const yearCache = new QuickLRU({ maxSize: 400 });
|
|
@@ -3774,8 +6741,8 @@ function getHolidaysForYear_(year) {
|
|
|
3774
6741
|
if (cached) {
|
|
3775
6742
|
return cached;
|
|
3776
6743
|
}
|
|
3777
|
-
const RH = new
|
|
3778
|
-
const pesach = new
|
|
6744
|
+
const RH = new HDate(1, TISHREI$1, year);
|
|
6745
|
+
const pesach = new HDate(15, NISAN$1, year);
|
|
3779
6746
|
const map = new Map();
|
|
3780
6747
|
function add(...events) {
|
|
3781
6748
|
for (const ev of events) {
|
|
@@ -3795,7 +6762,7 @@ function getHolidaysForYear_(year) {
|
|
|
3795
6762
|
}
|
|
3796
6763
|
}
|
|
3797
6764
|
for (const h of staticHolidays) {
|
|
3798
|
-
const hd = new
|
|
6765
|
+
const hd = new HDate(h.dd, h.mm, year);
|
|
3799
6766
|
const ev = new HolidayEvent(hd, h.desc, h.flags);
|
|
3800
6767
|
if (h.emoji)
|
|
3801
6768
|
ev.emoji = h.emoji;
|
|
@@ -3807,39 +6774,39 @@ function getHolidaysForYear_(year) {
|
|
|
3807
6774
|
add(new RoshHashanaEvent(RH, year, CHAG | LIGHT_CANDLES_TZEIS$1));
|
|
3808
6775
|
// Variable date holidays
|
|
3809
6776
|
const tzomGedaliahDay = RH.getDay() === THU ? 4 : 3;
|
|
3810
|
-
add(new HolidayEvent(new
|
|
6777
|
+
add(new HolidayEvent(new HDate(tzomGedaliahDay, TISHREI$1, year), holidayDesc.TZOM_GEDALIAH, MINOR_FAST$1));
|
|
3811
6778
|
// first SAT after RH
|
|
3812
|
-
add(new HolidayEvent(new
|
|
3813
|
-
const rchTevet =
|
|
3814
|
-
? new
|
|
3815
|
-
: new
|
|
6779
|
+
add(new HolidayEvent(new HDate(HDate.dayOnOrBefore(SAT$1, 7 + RH.abs())), holidayDesc.SHABBAT_SHUVA, SPECIAL_SHABBAT$1));
|
|
6780
|
+
const rchTevet = HDate.shortKislev(year)
|
|
6781
|
+
? new HDate(1, TEVET, year)
|
|
6782
|
+
: new HDate(30, KISLEV, year);
|
|
3816
6783
|
add(new HolidayEvent(rchTevet, holidayDesc.CHAG_HABANOT, MINOR_HOLIDAY$1));
|
|
3817
6784
|
// yes, we know Kislev 30-32 are wrong
|
|
3818
6785
|
// HDate() corrects the month automatically
|
|
3819
6786
|
for (let candles = 2; candles <= 8; candles++) {
|
|
3820
|
-
const hd = new
|
|
6787
|
+
const hd = new HDate(23 + candles, KISLEV, year);
|
|
3821
6788
|
add(new ChanukahEvent(hd, `Chanukah: ${candles} Candles`, MINOR_HOLIDAY$1 | CHANUKAH_CANDLES$1, {
|
|
3822
6789
|
chanukahDay: candles - 1,
|
|
3823
6790
|
emoji: chanukahEmoji + KEYCAP_DIGITS[candles],
|
|
3824
6791
|
}));
|
|
3825
6792
|
}
|
|
3826
|
-
add(new ChanukahEvent(new
|
|
3827
|
-
add(new AsaraBTevetEvent(new
|
|
6793
|
+
add(new ChanukahEvent(new HDate(32, KISLEV, year), holidayDesc.CHANUKAH_8TH_DAY, MINOR_HOLIDAY$1, { chanukahDay: 8, emoji: chanukahEmoji }));
|
|
6794
|
+
add(new AsaraBTevetEvent(new HDate(10, TEVET, year), holidayDesc.ASARA_BTEVET, MINOR_FAST$1));
|
|
3828
6795
|
const pesachAbs = pesach.abs();
|
|
3829
|
-
add(new HolidayEvent(new
|
|
3830
|
-
const haChodeshAbs =
|
|
3831
|
-
add(new HolidayEvent(new
|
|
6796
|
+
add(new HolidayEvent(new HDate(HDate.dayOnOrBefore(SAT$1, pesachAbs - 43)), holidayDesc.SHABBAT_SHEKALIM, SPECIAL_SHABBAT$1), new HolidayEvent(new HDate(HDate.dayOnOrBefore(SAT$1, pesachAbs - 30)), holidayDesc.SHABBAT_ZACHOR, SPECIAL_SHABBAT$1), new HolidayEvent(new HDate(pesachAbs - (pesach.getDay() === TUE ? 33 : 31)), holidayDesc.TAANIT_ESTHER, MINOR_FAST$1));
|
|
6797
|
+
const haChodeshAbs = HDate.dayOnOrBefore(SAT$1, pesachAbs - 14);
|
|
6798
|
+
add(new HolidayEvent(new HDate(haChodeshAbs - 7), holidayDesc.SHABBAT_PARAH, SPECIAL_SHABBAT$1), new HolidayEvent(new HDate(haChodeshAbs), holidayDesc.SHABBAT_HACHODESH, SPECIAL_SHABBAT$1), new HolidayEvent(new HDate(HDate.dayOnOrBefore(SAT$1, pesachAbs - 1)), holidayDesc.SHABBAT_HAGADOL, SPECIAL_SHABBAT$1), new HolidayEvent(
|
|
3832
6799
|
// if the fast falls on Shabbat, move to Thursday
|
|
3833
6800
|
pesach.prev().getDay() === SAT$1
|
|
3834
6801
|
? pesach.onOrBefore(THU)
|
|
3835
|
-
: new
|
|
3836
|
-
add(new HolidayEvent(new
|
|
6802
|
+
: new HDate(14, NISAN$1, year), holidayDesc.TAANIT_BECHOROT, MINOR_FAST$1));
|
|
6803
|
+
add(new HolidayEvent(new HDate(HDate.dayOnOrBefore(SAT$1, new HDate(1, TISHREI$1, year + 1).abs() - 4)), holidayDesc.LEIL_SELICHOT, MINOR_HOLIDAY$1, { emoji: '🕍' }));
|
|
3837
6804
|
if (pesach.getDay() === SUN) {
|
|
3838
|
-
add(new HolidayEvent(new
|
|
6805
|
+
add(new HolidayEvent(new HDate(16, ADAR_II, year), holidayDesc.PURIM_MESHULASH, MINOR_HOLIDAY$1));
|
|
3839
6806
|
}
|
|
3840
|
-
if (
|
|
3841
|
-
add(new HolidayEvent(new
|
|
3842
|
-
add(new HolidayEvent(new
|
|
6807
|
+
if (HDate.isLeapYear(year)) {
|
|
6808
|
+
add(new HolidayEvent(new HDate(14, ADAR_I, year), holidayDesc.PURIM_KATAN, MINOR_HOLIDAY$1, { emoji: '🎭️' }));
|
|
6809
|
+
add(new HolidayEvent(new HDate(15, ADAR_I, year), holidayDesc.SHUSHAN_PURIM_KATAN, MINOR_HOLIDAY$1, { emoji: '🎭️' }));
|
|
3843
6810
|
}
|
|
3844
6811
|
const nisan27dt = dateYomHaShoah(year);
|
|
3845
6812
|
if (nisan27dt) {
|
|
@@ -3851,13 +6818,13 @@ function getHolidaysForYear_(year) {
|
|
|
3851
6818
|
}
|
|
3852
6819
|
for (const h of staticModernHolidays) {
|
|
3853
6820
|
if (year >= h.firstYear) {
|
|
3854
|
-
let hd = new
|
|
6821
|
+
let hd = new HDate(h.dd, h.mm, year);
|
|
3855
6822
|
const dow = hd.getDay();
|
|
3856
6823
|
if (h.friSatMovetoThu && (dow === FRI$1 || dow === SAT$1)) {
|
|
3857
6824
|
hd = hd.onOrBefore(THU);
|
|
3858
6825
|
}
|
|
3859
6826
|
else if (h.friPostponeToSun && dow === FRI$1) {
|
|
3860
|
-
hd = new
|
|
6827
|
+
hd = new HDate(hd.abs() + 2);
|
|
3861
6828
|
}
|
|
3862
6829
|
else if (h.satPostponeToSun && dow === SAT$1) {
|
|
3863
6830
|
hd = hd.next();
|
|
@@ -3870,14 +6837,14 @@ function getHolidaysForYear_(year) {
|
|
|
3870
6837
|
add(ev);
|
|
3871
6838
|
}
|
|
3872
6839
|
}
|
|
3873
|
-
let tamuz17 = new
|
|
6840
|
+
let tamuz17 = new HDate(17, TAMUZ, year);
|
|
3874
6841
|
let tamuz17attrs;
|
|
3875
6842
|
if (tamuz17.getDay() === SAT$1) {
|
|
3876
|
-
tamuz17 = new
|
|
6843
|
+
tamuz17 = new HDate(18, TAMUZ, year);
|
|
3877
6844
|
tamuz17attrs = { observed: true };
|
|
3878
6845
|
}
|
|
3879
6846
|
add(new HolidayEvent(tamuz17, holidayDesc.TZOM_TAMMUZ, MINOR_FAST$1, tamuz17attrs));
|
|
3880
|
-
let av9dt = new
|
|
6847
|
+
let av9dt = new HDate(9, AV, year);
|
|
3881
6848
|
let av9title = holidayDesc.TISHA_BAV;
|
|
3882
6849
|
let av9attrs;
|
|
3883
6850
|
if (av9dt.getDay() === SAT$1) {
|
|
@@ -3886,38 +6853,38 @@ function getHolidaysForYear_(year) {
|
|
|
3886
6853
|
av9title += ' (observed)';
|
|
3887
6854
|
}
|
|
3888
6855
|
const av9abs = av9dt.abs();
|
|
3889
|
-
add(new HolidayEvent(new
|
|
3890
|
-
const monthsInYear =
|
|
6856
|
+
add(new HolidayEvent(new HDate(HDate.dayOnOrBefore(SAT$1, av9abs)), holidayDesc.SHABBAT_CHAZON, SPECIAL_SHABBAT$1), new HolidayEvent(av9dt.prev(), holidayDesc.EREV_TISHA_BAV, EREV$1 | MAJOR_FAST$1, av9attrs), new HolidayEvent(av9dt, av9title, MAJOR_FAST$1, av9attrs), new HolidayEvent(new HDate(HDate.dayOnOrBefore(SAT$1, av9abs + 7)), holidayDesc.SHABBAT_NACHAMU, SPECIAL_SHABBAT$1));
|
|
6857
|
+
const monthsInYear = HDate.monthsInYear(year);
|
|
3891
6858
|
for (let month = 1; month <= monthsInYear; month++) {
|
|
3892
|
-
const monthName =
|
|
6859
|
+
const monthName = HDate.getMonthName(month, year);
|
|
3893
6860
|
if ((month === NISAN$1
|
|
3894
|
-
?
|
|
3895
|
-
:
|
|
3896
|
-
add(new RoshChodeshEvent(new
|
|
3897
|
-
add(new RoshChodeshEvent(new
|
|
6861
|
+
? HDate.daysInMonth(HDate.monthsInYear(year - 1), year - 1)
|
|
6862
|
+
: HDate.daysInMonth(month - 1, year)) === 30) {
|
|
6863
|
+
add(new RoshChodeshEvent(new HDate(1, month, year), monthName));
|
|
6864
|
+
add(new RoshChodeshEvent(new HDate(30, month - 1, year), monthName));
|
|
3898
6865
|
}
|
|
3899
6866
|
else if (month !== TISHREI$1) {
|
|
3900
|
-
add(new RoshChodeshEvent(new
|
|
6867
|
+
add(new RoshChodeshEvent(new HDate(1, month, year), monthName));
|
|
3901
6868
|
}
|
|
3902
6869
|
}
|
|
3903
6870
|
// Begin: Yom Kippur Katan
|
|
3904
6871
|
// start at Iyyar because one may not fast during Nisan
|
|
3905
|
-
for (let month =
|
|
6872
|
+
for (let month = months.IYYAR; month <= monthsInYear; month++) {
|
|
3906
6873
|
const nextMonth = month + 1;
|
|
3907
6874
|
// Yom Kippur Katan is not observed on the day before Rosh Hashanah.
|
|
3908
6875
|
// Not observed prior to Rosh Chodesh Cheshvan because Yom Kippur has just passed.
|
|
3909
6876
|
// Not observed before Rosh Chodesh Tevet, because that day is Hanukkah.
|
|
3910
6877
|
if (nextMonth === TISHREI$1 ||
|
|
3911
|
-
nextMonth ===
|
|
6878
|
+
nextMonth === months.CHESHVAN ||
|
|
3912
6879
|
nextMonth === TEVET) {
|
|
3913
6880
|
continue;
|
|
3914
6881
|
}
|
|
3915
|
-
let ykk = new
|
|
6882
|
+
let ykk = new HDate(29, month, year);
|
|
3916
6883
|
const dow = ykk.getDay();
|
|
3917
6884
|
if (dow === FRI$1 || dow === SAT$1) {
|
|
3918
6885
|
ykk = ykk.onOrBefore(THU);
|
|
3919
6886
|
}
|
|
3920
|
-
const nextMonthName =
|
|
6887
|
+
const nextMonthName = HDate.getMonthName(nextMonth, year);
|
|
3921
6888
|
const ev = new YomKippurKatanEvent(ykk, nextMonthName);
|
|
3922
6889
|
add(ev);
|
|
3923
6890
|
}
|
|
@@ -3927,7 +6894,7 @@ function getHolidaysForYear_(year) {
|
|
|
3927
6894
|
// Birkat Hachamah appears only once every 28 years
|
|
3928
6895
|
const birkatHaChama = getBirkatHaChama(year);
|
|
3929
6896
|
if (birkatHaChama) {
|
|
3930
|
-
const hd = new
|
|
6897
|
+
const hd = new HDate(birkatHaChama);
|
|
3931
6898
|
add(new HolidayEvent(hd, holidayDesc.BIRKAT_HACHAMAH, MINOR_HOLIDAY$1, { emoji: '☀️' }));
|
|
3932
6899
|
}
|
|
3933
6900
|
yearCache.set(year, map);
|
|
@@ -3944,10 +6911,10 @@ function getHolidaysForYear_(year) {
|
|
|
3944
6911
|
* @private
|
|
3945
6912
|
*/
|
|
3946
6913
|
function getBirkatHaChama(year) {
|
|
3947
|
-
const leap =
|
|
6914
|
+
const leap = HDate.isLeapYear(year);
|
|
3948
6915
|
const startMonth = leap ? ADAR_II : NISAN$1;
|
|
3949
6916
|
const startDay = leap ? 20 : 1;
|
|
3950
|
-
const baseRd =
|
|
6917
|
+
const baseRd = HDate.hebrew2abs(year, startMonth, startDay);
|
|
3951
6918
|
for (let day = 0; day <= 40; day++) {
|
|
3952
6919
|
const abs = baseRd + day;
|
|
3953
6920
|
const elapsed = abs + 1373429;
|
|
@@ -3964,12 +6931,12 @@ function getBirkatHaChama(year) {
|
|
|
3964
6931
|
*/
|
|
3965
6932
|
function getHolidaysForYearArray(year, il) {
|
|
3966
6933
|
const yearMap = getHolidaysForYear_(year);
|
|
3967
|
-
const startAbs =
|
|
3968
|
-
const endAbs =
|
|
6934
|
+
const startAbs = HDate.hebrew2abs(year, TISHREI$1, 1);
|
|
6935
|
+
const endAbs = HDate.hebrew2abs(year + 1, TISHREI$1, 1) - 1;
|
|
3969
6936
|
let events = [];
|
|
3970
6937
|
const myFilter = il ? observedInIsrael : observedInDiaspora;
|
|
3971
6938
|
for (let absDt = startAbs; absDt <= endAbs; absDt++) {
|
|
3972
|
-
const hd = new
|
|
6939
|
+
const hd = new HDate(absDt);
|
|
3973
6940
|
const holidays = yearMap.get(hd.toString());
|
|
3974
6941
|
if (holidays) {
|
|
3975
6942
|
const filtered = holidays.filter(myFilter);
|
|
@@ -3991,14 +6958,14 @@ class MevarchimChodeshEvent extends Event {
|
|
|
3991
6958
|
*/
|
|
3992
6959
|
constructor(date, monthName, memo, locale) {
|
|
3993
6960
|
super(date, `${mevarchimChodeshStr} ${monthName}`, flags.SHABBAT_MEVARCHIM);
|
|
3994
|
-
this.monthName =
|
|
6961
|
+
this.monthName = Locale.gettext(monthName, locale);
|
|
3995
6962
|
if (memo) {
|
|
3996
6963
|
this.memo = memo;
|
|
3997
6964
|
}
|
|
3998
6965
|
else {
|
|
3999
6966
|
const hyear = date.getFullYear();
|
|
4000
6967
|
const hmonth = date.getMonth();
|
|
4001
|
-
const monNext = hmonth ===
|
|
6968
|
+
const monNext = hmonth === HDate.monthsInYear(hyear) ? months.NISAN : hmonth + 1;
|
|
4002
6969
|
const molad = new Molad(hyear, monNext);
|
|
4003
6970
|
this.memo = molad.render('en', { hour12: false });
|
|
4004
6971
|
}
|
|
@@ -4011,9 +6978,9 @@ class MevarchimChodeshEvent extends Event {
|
|
|
4011
6978
|
* @param [locale] Optional locale name (defaults to active locale).
|
|
4012
6979
|
*/
|
|
4013
6980
|
render(locale) {
|
|
4014
|
-
const monthName0 =
|
|
6981
|
+
const monthName0 = Locale.gettext(this.monthName, locale);
|
|
4015
6982
|
const monthName = monthName0.replace(/'/g, '’');
|
|
4016
|
-
return
|
|
6983
|
+
return Locale.gettext(mevarchimChodeshStr, locale) + ' ' + monthName;
|
|
4017
6984
|
}
|
|
4018
6985
|
/**
|
|
4019
6986
|
* Returns (translated) description of this event
|
|
@@ -4088,7 +7055,7 @@ const WHOLE = 2;
|
|
|
4088
7055
|
/**
|
|
4089
7056
|
* @private
|
|
4090
7057
|
*/
|
|
4091
|
-
function hallel_(events, hdate
|
|
7058
|
+
function hallel_(events, hdate) {
|
|
4092
7059
|
const whole = events
|
|
4093
7060
|
.filter(ev => {
|
|
4094
7061
|
const desc = ev.getDesc();
|
|
@@ -4098,7 +7065,7 @@ function hallel_(events, hdate$1) {
|
|
|
4098
7065
|
return (desc.startsWith('Chanukah') ||
|
|
4099
7066
|
desc.startsWith('Shavuot') ||
|
|
4100
7067
|
desc.startsWith('Sukkot') ||
|
|
4101
|
-
(month ===
|
|
7068
|
+
(month === months.NISAN &&
|
|
4102
7069
|
(mday === 15 || mday === 16) &&
|
|
4103
7070
|
ev.getFlags() & flags.CHAG) || // Pesach
|
|
4104
7071
|
desc === "Yom HaAtzma'ut" ||
|
|
@@ -4107,7 +7074,7 @@ function hallel_(events, hdate$1) {
|
|
|
4107
7074
|
.map(ev => {
|
|
4108
7075
|
return ev.getDate().abs();
|
|
4109
7076
|
});
|
|
4110
|
-
const abs = hdate
|
|
7077
|
+
const abs = hdate.abs();
|
|
4111
7078
|
if (whole.includes(abs)) {
|
|
4112
7079
|
return WHOLE;
|
|
4113
7080
|
}
|
|
@@ -4159,14 +7126,14 @@ const NONE = {
|
|
|
4159
7126
|
function tachanun(hdate, il) {
|
|
4160
7127
|
return tachanun0(hdate, il, true);
|
|
4161
7128
|
}
|
|
4162
|
-
function tachanun0(hdate
|
|
4163
|
-
const year = hdate
|
|
7129
|
+
function tachanun0(hdate, il, checkNext) {
|
|
7130
|
+
const year = hdate.yy;
|
|
4164
7131
|
const dates = tachanunYear(year, il);
|
|
4165
|
-
const abs = hdate
|
|
7132
|
+
const abs = hdate.abs();
|
|
4166
7133
|
if (dates.none.indexOf(abs) > -1) {
|
|
4167
7134
|
return NONE;
|
|
4168
7135
|
}
|
|
4169
|
-
const dow = hdate
|
|
7136
|
+
const dow = hdate.getDay();
|
|
4170
7137
|
const ret = {
|
|
4171
7138
|
shacharit: false,
|
|
4172
7139
|
mincha: false,
|
|
@@ -4180,7 +7147,7 @@ function tachanun0(hdate$1, il, checkNext) {
|
|
|
4180
7147
|
}
|
|
4181
7148
|
const tomorrow = abs + 1;
|
|
4182
7149
|
if (checkNext && dates.yesPrev.indexOf(tomorrow) === -1) {
|
|
4183
|
-
const tmp = tachanun0(new
|
|
7150
|
+
const tmp = tachanun0(new HDate(tomorrow), il, false);
|
|
4184
7151
|
ret.mincha = tmp.shacharit;
|
|
4185
7152
|
}
|
|
4186
7153
|
else {
|
|
@@ -4192,53 +7159,53 @@ function tachanun0(hdate$1, il, checkNext) {
|
|
|
4192
7159
|
return ret;
|
|
4193
7160
|
}
|
|
4194
7161
|
function tachanunYear(year, il) {
|
|
4195
|
-
const leap =
|
|
4196
|
-
const monthsInYear =
|
|
4197
|
-
let av9dt = new
|
|
7162
|
+
const leap = HDate.isLeapYear(year);
|
|
7163
|
+
const monthsInYear = HDate.monthsInYear(year);
|
|
7164
|
+
let av9dt = new HDate(9, months.AV, year);
|
|
4198
7165
|
if (av9dt.getDay() === 6) {
|
|
4199
7166
|
av9dt = av9dt.next();
|
|
4200
7167
|
}
|
|
4201
|
-
let shushPurim = new
|
|
7168
|
+
let shushPurim = new HDate(15, months.ADAR_II, year);
|
|
4202
7169
|
if (shushPurim.getDay() === 6) {
|
|
4203
7170
|
shushPurim = shushPurim.next();
|
|
4204
7171
|
}
|
|
4205
7172
|
const none = [
|
|
4206
|
-
new
|
|
7173
|
+
new HDate(2, months.TISHREI, year), // Rosh Hashana II
|
|
4207
7174
|
].concat(
|
|
4208
7175
|
// Rosh Chodesh - 1st of every month. Also includes RH day 1 (1 Tishrei)
|
|
4209
|
-
range(1, monthsInYear).map(month => new
|
|
7176
|
+
range(1, monthsInYear).map(month => new HDate(1, month, year)),
|
|
4210
7177
|
// Rosh Chodesh - 30th of months that have one
|
|
4211
7178
|
range(1, monthsInYear)
|
|
4212
|
-
.filter(month =>
|
|
4213
|
-
.map(month => new
|
|
7179
|
+
.filter(month => HDate.daysInMonth(month, year) === 30)
|
|
7180
|
+
.map(month => new HDate(30, month, year)),
|
|
4214
7181
|
// entire month of Nisan
|
|
4215
|
-
range(1,
|
|
7182
|
+
range(1, HDate.daysInMonth(months.NISAN, year)).map(mday => new HDate(mday, months.NISAN, year)), new HDate(18, months.IYYAR, year), // Lag BaOmer
|
|
4216
7183
|
// Rosh Chodesh Sivan thru Isru Chag
|
|
4217
|
-
range(1, 8 - (il ? 1 : 0)).map(mday => new
|
|
4218
|
-
new
|
|
4219
|
-
new
|
|
7184
|
+
range(1, 8 - (il ? 1 : 0)).map(mday => new HDate(mday, months.SIVAN, year)), av9dt, // Tisha B'Av
|
|
7185
|
+
new HDate(15, months.AV, year), // Tu B'Av
|
|
7186
|
+
new HDate(29, months.ELUL, year), // Erev Rosh Hashanah
|
|
4220
7187
|
// Erev Yom Kippur thru Isru Chag
|
|
4221
|
-
range(9, 24 - (il ? 1 : 0)).map(mday => new
|
|
7188
|
+
range(9, 24 - (il ? 1 : 0)).map(mday => new HDate(mday, months.TISHREI, year)),
|
|
4222
7189
|
// Chanukah
|
|
4223
|
-
range(25, 33).map(mday => new
|
|
4224
|
-
new
|
|
4225
|
-
shushPurim, leap ? new
|
|
7190
|
+
range(25, 33).map(mday => new HDate(mday, months.KISLEV, year)), new HDate(15, months.SHVAT, year), // Tu BiShvat
|
|
7191
|
+
new HDate(14, months.ADAR_II, year), // Purim
|
|
7192
|
+
shushPurim, leap ? new HDate(14, months.ADAR_I, year) : [] // Purim Katan
|
|
4226
7193
|
);
|
|
4227
7194
|
const some = [
|
|
4228
|
-
new
|
|
7195
|
+
new HDate(14, months.IYYAR, year), // Pesach Sheini
|
|
4229
7196
|
].concat(
|
|
4230
7197
|
// Until 14 Sivan
|
|
4231
|
-
range(1, 13).map(mday => new
|
|
7198
|
+
range(1, 13).map(mday => new HDate(mday, months.SIVAN, year)),
|
|
4232
7199
|
// Until after Rosh Chodesh Cheshvan
|
|
4233
|
-
range(20, 31).map(mday => new
|
|
7200
|
+
range(20, 31).map(mday => new HDate(mday, months.TISHREI, year)),
|
|
4234
7201
|
// Yom HaAtzma'ut, which changes based on day of week
|
|
4235
7202
|
year >= 5708 ? dateYomHaZikaron(year).next() : [],
|
|
4236
7203
|
// Yom Yerushalayim
|
|
4237
|
-
year >= 5727 ? new
|
|
7204
|
+
year >= 5727 ? new HDate(28, months.IYYAR, year) : []);
|
|
4238
7205
|
const yesPrev = [
|
|
4239
|
-
new
|
|
4240
|
-
new
|
|
4241
|
-
new
|
|
7206
|
+
new HDate(29, months.ELUL, year - 1), // Erev Rosh Hashanah
|
|
7207
|
+
new HDate(9, months.TISHREI, year), // Erev Yom Kippur
|
|
7208
|
+
new HDate(14, months.IYYAR, year), // Pesach Sheini
|
|
4242
7209
|
];
|
|
4243
7210
|
return {
|
|
4244
7211
|
none: none.map(hd => hd.abs()).sort((a, b) => a - b),
|
|
@@ -4247,7 +7214,7 @@ function tachanunYear(year, il) {
|
|
|
4247
7214
|
};
|
|
4248
7215
|
}
|
|
4249
7216
|
|
|
4250
|
-
const TISHREI =
|
|
7217
|
+
const TISHREI = months.TISHREI;
|
|
4251
7218
|
/**
|
|
4252
7219
|
* Gets the R.D. days for a number, Date, or HDate
|
|
4253
7220
|
* @private
|
|
@@ -4255,9 +7222,9 @@ const TISHREI = hdate.months.TISHREI;
|
|
|
4255
7222
|
function getAbs(d) {
|
|
4256
7223
|
if (typeof d === 'number')
|
|
4257
7224
|
return d;
|
|
4258
|
-
if (
|
|
4259
|
-
return
|
|
4260
|
-
if (
|
|
7225
|
+
if (isDate(d))
|
|
7226
|
+
return greg2abs(d);
|
|
7227
|
+
if (HDate.isHDate(d))
|
|
4261
7228
|
return d.abs();
|
|
4262
7229
|
throw new TypeError(`Invalid date type: ${d}`);
|
|
4263
7230
|
}
|
|
@@ -4266,7 +7233,7 @@ function getYear(options) {
|
|
|
4266
7233
|
return Number(options.year);
|
|
4267
7234
|
}
|
|
4268
7235
|
return options.isHebrewYear
|
|
4269
|
-
? new
|
|
7236
|
+
? new HDate().getFullYear()
|
|
4270
7237
|
: new Date().getFullYear();
|
|
4271
7238
|
}
|
|
4272
7239
|
/**
|
|
@@ -4300,7 +7267,7 @@ function getStartAndEnd(options) {
|
|
|
4300
7267
|
function getMonth(options) {
|
|
4301
7268
|
if (options.month) {
|
|
4302
7269
|
if (options.isHebrewYear) {
|
|
4303
|
-
return
|
|
7270
|
+
return HDate.monthNum(options.month);
|
|
4304
7271
|
}
|
|
4305
7272
|
else if (typeof options.month === 'number') {
|
|
4306
7273
|
return options.month;
|
|
@@ -4314,10 +7281,10 @@ function startEndGregorian(theMonth, theYear, numYears) {
|
|
|
4314
7281
|
if (theYear < 100) {
|
|
4315
7282
|
startGreg.setFullYear(theYear);
|
|
4316
7283
|
}
|
|
4317
|
-
const startAbs =
|
|
7284
|
+
const startAbs = greg2abs(startGreg);
|
|
4318
7285
|
let endAbs;
|
|
4319
7286
|
if (theMonth) {
|
|
4320
|
-
endAbs = startAbs +
|
|
7287
|
+
endAbs = startAbs + daysInGregMonth(theMonth, theYear) - 1;
|
|
4321
7288
|
}
|
|
4322
7289
|
else {
|
|
4323
7290
|
const endYear = theYear + numYears;
|
|
@@ -4325,16 +7292,16 @@ function startEndGregorian(theMonth, theYear, numYears) {
|
|
|
4325
7292
|
if (endYear < 100) {
|
|
4326
7293
|
endGreg.setFullYear(endYear);
|
|
4327
7294
|
}
|
|
4328
|
-
endAbs =
|
|
7295
|
+
endAbs = greg2abs(endGreg) - 1;
|
|
4329
7296
|
}
|
|
4330
7297
|
return [startAbs, endAbs];
|
|
4331
7298
|
}
|
|
4332
7299
|
function startEndHebrew(theMonth, theYear, numYears) {
|
|
4333
|
-
const startDate = new
|
|
7300
|
+
const startDate = new HDate(1, theMonth || TISHREI, theYear);
|
|
4334
7301
|
let startAbs = startDate.abs();
|
|
4335
7302
|
const endAbs = theMonth
|
|
4336
7303
|
? startAbs + startDate.daysInMonth()
|
|
4337
|
-
: new
|
|
7304
|
+
: new HDate(1, TISHREI, theYear + numYears).abs() - 1;
|
|
4338
7305
|
// for full Hebrew year, start on Erev Rosh Hashana which
|
|
4339
7306
|
// is technically in the previous Hebrew year
|
|
4340
7307
|
// (but conveniently lets us get candle-lighting time for Erev)
|
|
@@ -4464,13 +7431,13 @@ function calendar(options = {}) {
|
|
|
4464
7431
|
throw new TypeError(`Invalid options.locale: ${options.locale}`);
|
|
4465
7432
|
}
|
|
4466
7433
|
const locale = options.ashkenazi ? 'ashkenazi' : options.locale;
|
|
4467
|
-
const translationObj =
|
|
7434
|
+
const translationObj = Locale.useLocale(locale);
|
|
4468
7435
|
if (!translationObj) {
|
|
4469
7436
|
throw new TypeError(`Locale '${locale}' not found; did you forget to import @hebcal/locales?`);
|
|
4470
7437
|
}
|
|
4471
7438
|
}
|
|
4472
7439
|
else {
|
|
4473
|
-
|
|
7440
|
+
Locale.useLocale('en');
|
|
4474
7441
|
}
|
|
4475
7442
|
const evts = [];
|
|
4476
7443
|
let sedra;
|
|
@@ -4482,12 +7449,12 @@ function calendar(options = {}) {
|
|
|
4482
7449
|
warnUnrecognizedOptions(options);
|
|
4483
7450
|
const startAbs = startAndEnd[0];
|
|
4484
7451
|
const endAbs = startAndEnd[1];
|
|
4485
|
-
const startGreg =
|
|
7452
|
+
const startGreg = abs2greg(startAbs);
|
|
4486
7453
|
if (startGreg.getFullYear() < 100) {
|
|
4487
7454
|
options.candlelighting = false;
|
|
4488
7455
|
}
|
|
4489
7456
|
for (let abs = startAbs; abs <= endAbs; abs++) {
|
|
4490
|
-
const hd = new
|
|
7457
|
+
const hd = new HDate(abs);
|
|
4491
7458
|
const hyear = hd.getFullYear();
|
|
4492
7459
|
if (hyear !== currentYear) {
|
|
4493
7460
|
currentYear = hyear;
|
|
@@ -4496,8 +7463,8 @@ function calendar(options = {}) {
|
|
|
4496
7463
|
sedra = getSedra(currentYear, il);
|
|
4497
7464
|
}
|
|
4498
7465
|
if (options.omer) {
|
|
4499
|
-
beginOmer =
|
|
4500
|
-
endOmer =
|
|
7466
|
+
beginOmer = HDate.hebrew2abs(currentYear, NISAN, 16);
|
|
7467
|
+
endOmer = HDate.hebrew2abs(currentYear, SIVAN, 5);
|
|
4501
7468
|
}
|
|
4502
7469
|
}
|
|
4503
7470
|
const prevEventsLength = evts.length;
|
|
@@ -4518,7 +7485,7 @@ function calendar(options = {}) {
|
|
|
4518
7485
|
if (options.yizkor) {
|
|
4519
7486
|
const mm = hd.getMonth();
|
|
4520
7487
|
const dd = hd.getDate();
|
|
4521
|
-
if ((mm ===
|
|
7488
|
+
if ((mm === months.TISHREI && (dd === 10 || dd === 22)) ||
|
|
4522
7489
|
(mm === NISAN && dd === (il ? 21 : 22)) ||
|
|
4523
7490
|
(mm === SIVAN && dd === (il ? 6 : 7))) {
|
|
4524
7491
|
const linkedEvent = holidays.filter(ev => ev.observedIn(il))[0];
|
|
@@ -4579,9 +7546,9 @@ function calendar(options = {}) {
|
|
|
4579
7546
|
}
|
|
4580
7547
|
const FRI = 5;
|
|
4581
7548
|
const SAT = 6;
|
|
4582
|
-
const NISAN =
|
|
4583
|
-
const SIVAN =
|
|
4584
|
-
const ELUL =
|
|
7549
|
+
const NISAN = months.NISAN;
|
|
7550
|
+
const SIVAN = months.SIVAN;
|
|
7551
|
+
const ELUL = months.ELUL;
|
|
4585
7552
|
const LIGHT_CANDLES = flags.LIGHT_CANDLES;
|
|
4586
7553
|
const YOM_TOV_ENDS = flags.YOM_TOV_ENDS;
|
|
4587
7554
|
const CHUL_ONLY = flags.CHUL_ONLY;
|
|
@@ -4930,15 +7897,15 @@ function appendHolidayAndRelated(candlesEv, events, ev, options, isFriday, isSat
|
|
|
4930
7897
|
function makeMoladAndMevarchimChodesh(hd, options) {
|
|
4931
7898
|
const evts = [];
|
|
4932
7899
|
const hmonth = hd.getMonth();
|
|
4933
|
-
const hdate
|
|
4934
|
-
if (hmonth !== ELUL && hdate
|
|
7900
|
+
const hdate = hd.getDate();
|
|
7901
|
+
if (hmonth !== ELUL && hdate >= 23 && hdate <= 29) {
|
|
4935
7902
|
const hyear = hd.getFullYear();
|
|
4936
|
-
const monNext = hmonth ===
|
|
7903
|
+
const monNext = hmonth === HDate.monthsInYear(hyear) ? NISAN : hmonth + 1;
|
|
4937
7904
|
if (options.molad) {
|
|
4938
7905
|
evts.push(new MoladEvent(hd, hyear, monNext, options));
|
|
4939
7906
|
}
|
|
4940
7907
|
if (options.shabbatMevarchim) {
|
|
4941
|
-
const nextMonthName =
|
|
7908
|
+
const nextMonthName = HDate.getMonthName(monNext, hyear);
|
|
4942
7909
|
const molad = new Molad(hyear, monNext);
|
|
4943
7910
|
const memo = molad.render(options.locale || 'en', options);
|
|
4944
7911
|
evts.push(new MevarchimChodeshEvent(hd, nextMonthName, memo, options.locale));
|
|
@@ -5144,11 +8111,11 @@ class HebrewCalendar {
|
|
|
5144
8111
|
* @returns anniversary occurring in `hyear`
|
|
5145
8112
|
*/
|
|
5146
8113
|
static getBirthdayOrAnniversary(hyear, gdate) {
|
|
5147
|
-
const dt =
|
|
8114
|
+
const dt = getBirthdayHD(hyear, gdate);
|
|
5148
8115
|
if (typeof dt === 'undefined') {
|
|
5149
8116
|
return dt;
|
|
5150
8117
|
}
|
|
5151
|
-
return new
|
|
8118
|
+
return new HDate(dt);
|
|
5152
8119
|
}
|
|
5153
8120
|
/**
|
|
5154
8121
|
* Calculates yahrzeit.
|
|
@@ -5185,11 +8152,11 @@ class HebrewCalendar {
|
|
|
5185
8152
|
* @returns anniversary occurring in hyear
|
|
5186
8153
|
*/
|
|
5187
8154
|
static getYahrzeit(hyear, gdate) {
|
|
5188
|
-
const dt =
|
|
8155
|
+
const dt = getYahrzeitHD(hyear, gdate);
|
|
5189
8156
|
if (typeof dt === 'undefined') {
|
|
5190
8157
|
return dt;
|
|
5191
8158
|
}
|
|
5192
|
-
return new
|
|
8159
|
+
return new HDate(dt);
|
|
5193
8160
|
}
|
|
5194
8161
|
/**
|
|
5195
8162
|
* Lower-level holidays interface, which returns a `Map` of `Event`s indexed by
|
|
@@ -5223,7 +8190,7 @@ class HebrewCalendar {
|
|
|
5223
8190
|
if (date.getDay() < 3 || date.getDay() > 4) {
|
|
5224
8191
|
return false;
|
|
5225
8192
|
}
|
|
5226
|
-
const today = new
|
|
8193
|
+
const today = new HDate(date);
|
|
5227
8194
|
const friday = today.after(5);
|
|
5228
8195
|
const tomorrow = today.next();
|
|
5229
8196
|
if (!isChag(friday, il) || isChag(today, il) || !isChag(tomorrow, il)) {
|
|
@@ -5301,52 +8268,24 @@ function isChag(date, il) {
|
|
|
5301
8268
|
return chag.length !== 0;
|
|
5302
8269
|
}
|
|
5303
8270
|
|
|
5304
|
-
Object.defineProperty(exports, "HDate", {
|
|
5305
|
-
enumerable: true,
|
|
5306
|
-
get: function () { return hdate.HDate; }
|
|
5307
|
-
});
|
|
5308
|
-
Object.defineProperty(exports, "Locale", {
|
|
5309
|
-
enumerable: true,
|
|
5310
|
-
get: function () { return hdate.Locale; }
|
|
5311
|
-
});
|
|
5312
|
-
Object.defineProperty(exports, "gematriya", {
|
|
5313
|
-
enumerable: true,
|
|
5314
|
-
get: function () { return hdate.gematriya; }
|
|
5315
|
-
});
|
|
5316
|
-
Object.defineProperty(exports, "gematriyaStrToNum", {
|
|
5317
|
-
enumerable: true,
|
|
5318
|
-
get: function () { return hdate.gematriyaStrToNum; }
|
|
5319
|
-
});
|
|
5320
|
-
Object.defineProperty(exports, "greg", {
|
|
5321
|
-
enumerable: true,
|
|
5322
|
-
get: function () { return hdate.greg; }
|
|
5323
|
-
});
|
|
5324
|
-
Object.defineProperty(exports, "months", {
|
|
5325
|
-
enumerable: true,
|
|
5326
|
-
get: function () { return hdate.months; }
|
|
5327
|
-
});
|
|
5328
|
-
Object.defineProperty(exports, "GeoLocation", {
|
|
5329
|
-
enumerable: true,
|
|
5330
|
-
get: function () { return noaa.GeoLocation; }
|
|
5331
|
-
});
|
|
5332
|
-
Object.defineProperty(exports, "NOAACalculator", {
|
|
5333
|
-
enumerable: true,
|
|
5334
|
-
get: function () { return noaa.NOAACalculator; }
|
|
5335
|
-
});
|
|
5336
8271
|
exports.AsaraBTevetEvent = AsaraBTevetEvent;
|
|
5337
8272
|
exports.CandleLightingEvent = CandleLightingEvent;
|
|
5338
8273
|
exports.ChanukahEvent = ChanukahEvent;
|
|
5339
8274
|
exports.DailyLearning = DailyLearning;
|
|
5340
8275
|
exports.Event = Event;
|
|
5341
8276
|
exports.FastDayEvent = FastDayEvent;
|
|
8277
|
+
exports.GeoLocation = GeoLocation;
|
|
8278
|
+
exports.HDate = HDate;
|
|
5342
8279
|
exports.HavdalahEvent = HavdalahEvent;
|
|
5343
8280
|
exports.HebrewCalendar = HebrewCalendar;
|
|
5344
8281
|
exports.HebrewDateEvent = HebrewDateEvent;
|
|
5345
8282
|
exports.HolidayEvent = HolidayEvent;
|
|
8283
|
+
exports.Locale = Locale;
|
|
5346
8284
|
exports.Location = Location;
|
|
5347
8285
|
exports.MevarchimChodeshEvent = MevarchimChodeshEvent;
|
|
5348
8286
|
exports.Molad = Molad;
|
|
5349
8287
|
exports.MoladEvent = MoladEvent;
|
|
8288
|
+
exports.NOAACalculator = NOAACalculator;
|
|
5350
8289
|
exports.OmerEvent = OmerEvent;
|
|
5351
8290
|
exports.ParshaEvent = ParshaEvent;
|
|
5352
8291
|
exports.RoshChodeshEvent = RoshChodeshEvent;
|
|
@@ -5357,9 +8296,12 @@ exports.TimedEvent = TimedEvent;
|
|
|
5357
8296
|
exports.YomKippurKatanEvent = YomKippurKatanEvent;
|
|
5358
8297
|
exports.Zmanim = Zmanim;
|
|
5359
8298
|
exports.flags = flags;
|
|
8299
|
+
exports.gematriya = gematriya;
|
|
8300
|
+
exports.gematriyaStrToNum = gematriyaStrToNum;
|
|
5360
8301
|
exports.getHolidaysOnDate = getHolidaysOnDate;
|
|
5361
8302
|
exports.getSedra = getSedra;
|
|
5362
8303
|
exports.holidayDesc = holidayDesc;
|
|
8304
|
+
exports.months = months;
|
|
5363
8305
|
exports.parshaYear = parshaYear;
|
|
5364
8306
|
exports.parshiot = parshiot;
|
|
5365
8307
|
exports.version = version;
|