@hebcal/core 4.5.1 → 5.0.0-rc1
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/README.md +1109 -457
- package/dist/bundle.js +5124 -1331
- package/dist/bundle.min.js +2 -2
- package/dist/index.js +2216 -1525
- package/dist/index.mjs +2215 -1524
- package/hebcal.d.ts +7 -121
- package/package.json +10 -8
- package/dist/greg0.mjs +0 -159
- package/dist/hdate-bundle.js +0 -1864
- package/dist/hdate-bundle.min.js +0 -2
- package/dist/hdate.js +0 -1853
- package/dist/hdate.mjs +0 -1909
- package/dist/hdate0-bundle.js +0 -444
- package/dist/hdate0-bundle.min.js +0 -2
- package/dist/hdate0.mjs +0 -465
package/dist/index.mjs
CHANGED
|
@@ -1,247 +1,4 @@
|
|
|
1
|
-
/*! @hebcal/core
|
|
2
|
-
/*
|
|
3
|
-
* More minimal greg routines
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/** @private */
|
|
7
|
-
const lengths = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
8
|
-
/** @private */
|
|
9
|
-
const monthLengths = [lengths, lengths.slice()];
|
|
10
|
-
monthLengths[1][2] = 29;
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* @private
|
|
14
|
-
* @param {number} x
|
|
15
|
-
* @param {number} y
|
|
16
|
-
* @return {number}
|
|
17
|
-
*/
|
|
18
|
-
function mod(x, y) {
|
|
19
|
-
return x - y * Math.floor(x / y);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* @private
|
|
24
|
-
* @param {number} x
|
|
25
|
-
* @param {number} y
|
|
26
|
-
* @return {number}
|
|
27
|
-
*/
|
|
28
|
-
function quotient(x, y) {
|
|
29
|
-
return Math.floor(x / y);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Returns true if the Gregorian year is a leap year
|
|
34
|
-
* @private
|
|
35
|
-
* @param {number} year Gregorian year
|
|
36
|
-
* @return {boolean}
|
|
37
|
-
*/
|
|
38
|
-
function isLeapYear$1(year) {
|
|
39
|
-
return !(year % 4) && (!!(year % 100) || !(year % 400));
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Number of days in the Gregorian month for given year
|
|
44
|
-
* @private
|
|
45
|
-
* @param {number} month Gregorian month (1=January, 12=December)
|
|
46
|
-
* @param {number} year Gregorian year
|
|
47
|
-
* @return {number}
|
|
48
|
-
*/
|
|
49
|
-
function daysInMonth$1(month, year) {
|
|
50
|
-
// 1 based months
|
|
51
|
-
return monthLengths[+isLeapYear$1(year)][month];
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Returns true if the object is a Javascript Date
|
|
56
|
-
* @private
|
|
57
|
-
* @param {Object} obj
|
|
58
|
-
* @return {boolean}
|
|
59
|
-
*/
|
|
60
|
-
function isDate(obj) {
|
|
61
|
-
return typeof obj === 'object' && Date.prototype === obj.__proto__;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/*
|
|
65
|
-
const ABS_14SEP1752 = 639797;
|
|
66
|
-
const ABS_2SEP1752 = 639785;
|
|
67
|
-
*/
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Converts Gregorian date to absolute R.D. (Rata Die) days
|
|
71
|
-
* @private
|
|
72
|
-
* @param {Date} date Gregorian date
|
|
73
|
-
* @return {number}
|
|
74
|
-
*/
|
|
75
|
-
function greg2abs(date) {
|
|
76
|
-
if (!isDate(date)) {
|
|
77
|
-
throw new TypeError(`Argument not a Date: ${date}`);
|
|
78
|
-
}
|
|
79
|
-
const abs = toFixed(date.getFullYear(), date.getMonth() + 1, date.getDate());
|
|
80
|
-
/*
|
|
81
|
-
if (abs < ABS_14SEP1752 && abs > ABS_2SEP1752) {
|
|
82
|
-
throw new RangeError(`Invalid Date: ${date}`);
|
|
83
|
-
}
|
|
84
|
-
*/
|
|
85
|
-
return abs;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* @private
|
|
90
|
-
* @param {number} abs - R.D. number of days
|
|
91
|
-
* @return {number}
|
|
92
|
-
*/
|
|
93
|
-
function yearFromFixed(abs) {
|
|
94
|
-
const l0 = abs - 1;
|
|
95
|
-
const n400 = quotient(l0, 146097);
|
|
96
|
-
const d1 = mod(l0, 146097);
|
|
97
|
-
const n100 = quotient(d1, 36524);
|
|
98
|
-
const d2 = mod(d1, 36524);
|
|
99
|
-
const n4 = quotient(d2, 1461);
|
|
100
|
-
const d3 = mod(d2, 1461);
|
|
101
|
-
const n1 = quotient(d3, 365);
|
|
102
|
-
const year = 400 * n400 + 100 * n100 + 4 * n4 + n1;
|
|
103
|
-
return n100 != 4 && n1 != 4 ? year + 1 : year;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* @private
|
|
108
|
-
* @param {number} year
|
|
109
|
-
* @param {number} month (1-12)
|
|
110
|
-
* @param {number} day (1-31)
|
|
111
|
-
* @return {number}
|
|
112
|
-
*/
|
|
113
|
-
function toFixed(year, month, day) {
|
|
114
|
-
const py = year - 1;
|
|
115
|
-
return 365 * py + quotient(py, 4) - quotient(py, 100) + quotient(py, 400) + quotient(367 * month - 362, 12) + (month <= 2 ? 0 : isLeapYear$1(year) ? -1 : -2) + day;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Converts from Rata Die (R.D. number) to Gregorian date.
|
|
120
|
-
* See the footnote on page 384 of ``Calendrical Calculations, Part II:
|
|
121
|
-
* Three Historical Calendars'' by E. M. Reingold, N. Dershowitz, and S. M.
|
|
122
|
-
* Clamen, Software--Practice and Experience, Volume 23, Number 4
|
|
123
|
-
* (April, 1993), pages 383-404 for an explanation.
|
|
124
|
-
* @private
|
|
125
|
-
* @param {number} abs - R.D. number of days
|
|
126
|
-
* @return {Date}
|
|
127
|
-
*/
|
|
128
|
-
function abs2greg(abs) {
|
|
129
|
-
if (typeof abs !== 'number') {
|
|
130
|
-
throw new TypeError(`Argument 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 : isLeapYear$1(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
|
-
/*
|
|
151
|
-
Hebcal - A Jewish Calendar Generator
|
|
152
|
-
Copyright (c) 1994-2020 Danny Sadinoff
|
|
153
|
-
Portions copyright Eyal Schachter and Michael J. Radwin
|
|
154
|
-
|
|
155
|
-
https://github.com/hebcal/hebcal-es6
|
|
156
|
-
|
|
157
|
-
This program is free software; you can redistribute it and/or
|
|
158
|
-
modify it under the terms of the GNU General Public License
|
|
159
|
-
as published by the Free Software Foundation; either version 2
|
|
160
|
-
of the License, or (at your option) any later version.
|
|
161
|
-
|
|
162
|
-
This program is distributed in the hope that it will be useful,
|
|
163
|
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
164
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
165
|
-
GNU General Public License for more details.
|
|
166
|
-
|
|
167
|
-
You should have received a copy of the GNU General Public License
|
|
168
|
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
169
|
-
*/
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Gregorian date helper functions.
|
|
174
|
-
*/
|
|
175
|
-
const greg = {
|
|
176
|
-
/**
|
|
177
|
-
* Long names of the Gregorian months (1='January', 12='December')
|
|
178
|
-
* @readonly
|
|
179
|
-
* @type {string[]}
|
|
180
|
-
*/
|
|
181
|
-
monthNames: ['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
|
|
182
|
-
/**
|
|
183
|
-
* Returns true if the Gregorian year is a leap year
|
|
184
|
-
* @function
|
|
185
|
-
* @param {number} year Gregorian year
|
|
186
|
-
* @return {boolean}
|
|
187
|
-
*/
|
|
188
|
-
isLeapYear: isLeapYear$1,
|
|
189
|
-
/**
|
|
190
|
-
* Number of days in the Gregorian month for given year
|
|
191
|
-
* @function
|
|
192
|
-
* @param {number} month Gregorian month (1=January, 12=December)
|
|
193
|
-
* @param {number} year Gregorian year
|
|
194
|
-
* @return {number}
|
|
195
|
-
*/
|
|
196
|
-
daysInMonth: daysInMonth$1,
|
|
197
|
-
/**
|
|
198
|
-
* Returns true if the object is a Javascript Date
|
|
199
|
-
* @function
|
|
200
|
-
* @param {Object} obj
|
|
201
|
-
* @return {boolean}
|
|
202
|
-
*/
|
|
203
|
-
isDate: isDate,
|
|
204
|
-
/**
|
|
205
|
-
* Returns number of days since January 1 of that year
|
|
206
|
-
* @deprecated
|
|
207
|
-
* @param {Date} date Gregorian date
|
|
208
|
-
* @return {number}
|
|
209
|
-
*/
|
|
210
|
-
dayOfYear: function (date) {
|
|
211
|
-
if (!isDate(date)) {
|
|
212
|
-
throw new TypeError(`Argument not a Date: ${date}`);
|
|
213
|
-
}
|
|
214
|
-
const month = date.getMonth();
|
|
215
|
-
let doy = date.getDate() + 31 * month;
|
|
216
|
-
if (month > 1) {
|
|
217
|
-
// FEB
|
|
218
|
-
doy -= Math.floor((4 * (month + 1) + 23) / 10);
|
|
219
|
-
if (isLeapYear$1(date.getFullYear())) {
|
|
220
|
-
doy++;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
return doy;
|
|
224
|
-
},
|
|
225
|
-
/**
|
|
226
|
-
* Converts Gregorian date to absolute R.D. (Rata Die) days
|
|
227
|
-
* @function
|
|
228
|
-
* @param {Date} date Gregorian date
|
|
229
|
-
* @return {number}
|
|
230
|
-
*/
|
|
231
|
-
greg2abs: greg2abs,
|
|
232
|
-
/**
|
|
233
|
-
* Converts from Rata Die (R.D. number) to Gregorian date.
|
|
234
|
-
* See the footnote on page 384 of ``Calendrical Calculations, Part II:
|
|
235
|
-
* Three Historical Calendars'' by E. M. Reingold, N. Dershowitz, and S. M.
|
|
236
|
-
* Clamen, Software--Practice and Experience, Volume 23, Number 4
|
|
237
|
-
* (April, 1993), pages 383-404 for an explanation.
|
|
238
|
-
* @function
|
|
239
|
-
* @param {number} theDate - R.D. number of days
|
|
240
|
-
* @return {Date}
|
|
241
|
-
*/
|
|
242
|
-
abs2greg: abs2greg
|
|
243
|
-
};
|
|
244
|
-
|
|
1
|
+
/*! @hebcal/core v5.0.0-rc1 */
|
|
245
2
|
const GERESH = '׳';
|
|
246
3
|
const GERSHAYIM = '״';
|
|
247
4
|
const heb2num = {
|
|
@@ -268,10 +25,10 @@ const heb2num = {
|
|
|
268
25
|
'ש': 300,
|
|
269
26
|
'ת': 400
|
|
270
27
|
};
|
|
271
|
-
const num2heb =
|
|
28
|
+
const num2heb = new Map();
|
|
272
29
|
Object.keys(heb2num).forEach(key => {
|
|
273
30
|
const val = heb2num[key];
|
|
274
|
-
num2heb
|
|
31
|
+
num2heb.set(val, key);
|
|
275
32
|
});
|
|
276
33
|
|
|
277
34
|
/**
|
|
@@ -324,19 +81,19 @@ function gematriya(number) {
|
|
|
324
81
|
if (thousands > 0 && thousands !== 5) {
|
|
325
82
|
const tdigits = num2digits(thousands);
|
|
326
83
|
for (const tdig of tdigits) {
|
|
327
|
-
str += num2heb
|
|
84
|
+
str += num2heb.get(tdig);
|
|
328
85
|
}
|
|
329
86
|
str += GERESH;
|
|
330
87
|
}
|
|
331
88
|
const digits = num2digits(num % 1000);
|
|
332
89
|
if (digits.length == 1) {
|
|
333
|
-
return str + num2heb
|
|
90
|
+
return str + num2heb.get(digits[0]) + GERESH;
|
|
334
91
|
}
|
|
335
92
|
for (let i = 0; i < digits.length; i++) {
|
|
336
93
|
if (i + 1 === digits.length) {
|
|
337
94
|
str += GERSHAYIM;
|
|
338
95
|
}
|
|
339
|
-
str += num2heb
|
|
96
|
+
str += num2heb.get(digits[i]);
|
|
340
97
|
}
|
|
341
98
|
return str;
|
|
342
99
|
}
|
|
@@ -384,7 +141,7 @@ const alias = {
|
|
|
384
141
|
};
|
|
385
142
|
|
|
386
143
|
/** @private */
|
|
387
|
-
const locales =
|
|
144
|
+
const locales = new Map();
|
|
388
145
|
/** @private */
|
|
389
146
|
let activeLocale = null;
|
|
390
147
|
/** @private */
|
|
@@ -408,7 +165,7 @@ class Locale {
|
|
|
408
165
|
*/
|
|
409
166
|
static lookupTranslation(id, locale) {
|
|
410
167
|
const locale0 = locale === null || locale === void 0 ? void 0 : locale.toLowerCase();
|
|
411
|
-
const loc = typeof locale == 'string' && locales
|
|
168
|
+
const loc = typeof locale == 'string' && locales.get(locale0) || activeLocale;
|
|
412
169
|
const array = loc[id];
|
|
413
170
|
if (array && array.length && array[0].length) {
|
|
414
171
|
return array[0];
|
|
@@ -442,7 +199,7 @@ class Locale {
|
|
|
442
199
|
if (typeof data.contexts !== 'object' || typeof data.contexts[''] !== 'object') {
|
|
443
200
|
throw new TypeError(`Locale '${locale}' invalid compact format`);
|
|
444
201
|
}
|
|
445
|
-
locales
|
|
202
|
+
locales.set(locale.toLowerCase(), data.contexts['']);
|
|
446
203
|
}
|
|
447
204
|
|
|
448
205
|
/**
|
|
@@ -456,7 +213,7 @@ class Locale {
|
|
|
456
213
|
throw new TypeError(`Invalid locale name: ${locale}`);
|
|
457
214
|
}
|
|
458
215
|
const locale0 = locale.toLowerCase();
|
|
459
|
-
const loc = locales
|
|
216
|
+
const loc = locales.get(locale0);
|
|
460
217
|
if (!loc) {
|
|
461
218
|
throw new TypeError(`Unknown locale: ${locale}`);
|
|
462
219
|
}
|
|
@@ -484,7 +241,7 @@ class Locale {
|
|
|
484
241
|
throw new TypeError(`Invalid locale name: ${locale}`);
|
|
485
242
|
}
|
|
486
243
|
const locale0 = locale.toLowerCase();
|
|
487
|
-
const loc = locales
|
|
244
|
+
const loc = locales.get(locale0);
|
|
488
245
|
if (!loc) {
|
|
489
246
|
throw new TypeError(`Unknown locale: ${locale}`);
|
|
490
247
|
}
|
|
@@ -505,7 +262,7 @@ class Locale {
|
|
|
505
262
|
*/
|
|
506
263
|
static useLocale(locale) {
|
|
507
264
|
const locale0 = locale.toLowerCase();
|
|
508
|
-
const obj = locales
|
|
265
|
+
const obj = locales.get(locale0);
|
|
509
266
|
if (!obj) {
|
|
510
267
|
throw new RangeError(`Locale '${locale}' not found`);
|
|
511
268
|
}
|
|
@@ -527,7 +284,8 @@ class Locale {
|
|
|
527
284
|
* @return {string[]}
|
|
528
285
|
*/
|
|
529
286
|
static getLocaleNames() {
|
|
530
|
-
|
|
287
|
+
const keys = Array.from(locales.keys());
|
|
288
|
+
return keys.sort((a, b) => a.localeCompare(b));
|
|
531
289
|
}
|
|
532
290
|
|
|
533
291
|
/**
|
|
@@ -586,10 +344,170 @@ Locale.addLocale('s', noopLocale);
|
|
|
586
344
|
Locale.addLocale('', noopLocale);
|
|
587
345
|
Locale.useLocale('en');
|
|
588
346
|
|
|
347
|
+
/** @private */
|
|
348
|
+
const lengths = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
349
|
+
/** @private */
|
|
350
|
+
const monthLengths = [
|
|
351
|
+
lengths,
|
|
352
|
+
lengths.slice(),
|
|
353
|
+
];
|
|
354
|
+
monthLengths[1][2] = 29;
|
|
355
|
+
/**
|
|
356
|
+
* @private
|
|
357
|
+
*/
|
|
358
|
+
function mod$1(x, y) {
|
|
359
|
+
return x - y * Math.floor(x / y);
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* @private
|
|
363
|
+
*/
|
|
364
|
+
function quotient(x, y) {
|
|
365
|
+
return Math.floor(x / y);
|
|
366
|
+
}
|
|
589
367
|
/*
|
|
590
|
-
|
|
368
|
+
const ABS_14SEP1752 = 639797;
|
|
369
|
+
const ABS_2SEP1752 = 639785;
|
|
370
|
+
*/
|
|
371
|
+
/**
|
|
372
|
+
* Gregorian date helper functions.
|
|
591
373
|
*/
|
|
374
|
+
var greg;
|
|
375
|
+
(function (greg) {
|
|
376
|
+
/**
|
|
377
|
+
* Long names of the Gregorian months (1='January', 12='December')
|
|
378
|
+
* @readonly
|
|
379
|
+
* @type {string[]}
|
|
380
|
+
*/
|
|
381
|
+
greg.monthNames = [
|
|
382
|
+
'',
|
|
383
|
+
'January',
|
|
384
|
+
'February',
|
|
385
|
+
'March',
|
|
386
|
+
'April',
|
|
387
|
+
'May',
|
|
388
|
+
'June',
|
|
389
|
+
'July',
|
|
390
|
+
'August',
|
|
391
|
+
'September',
|
|
392
|
+
'October',
|
|
393
|
+
'November',
|
|
394
|
+
'December',
|
|
395
|
+
];
|
|
396
|
+
/**
|
|
397
|
+
* Returns true if the Gregorian year is a leap year
|
|
398
|
+
* @param {number} year Gregorian year
|
|
399
|
+
* @return {boolean}
|
|
400
|
+
*/
|
|
401
|
+
function isLeapYear(year) {
|
|
402
|
+
return !(year % 4) && (!!(year % 100) || !(year % 400));
|
|
403
|
+
}
|
|
404
|
+
greg.isLeapYear = isLeapYear;
|
|
405
|
+
/**
|
|
406
|
+
* Number of days in the Gregorian month for given year
|
|
407
|
+
* @param {number} month Gregorian month (1=January, 12=December)
|
|
408
|
+
* @param {number} year Gregorian year
|
|
409
|
+
* @return {number}
|
|
410
|
+
*/
|
|
411
|
+
function daysInMonth(month, year) {
|
|
412
|
+
// 1 based months
|
|
413
|
+
return monthLengths[+isLeapYear(year)][month];
|
|
414
|
+
}
|
|
415
|
+
greg.daysInMonth = daysInMonth;
|
|
416
|
+
/**
|
|
417
|
+
* Returns true if the object is a Javascript Date
|
|
418
|
+
* @param {Object} obj
|
|
419
|
+
* @return {boolean}
|
|
420
|
+
*/
|
|
421
|
+
function isDate(obj) {
|
|
422
|
+
return typeof obj === 'object' && Date.prototype.isPrototypeOf(obj);
|
|
423
|
+
}
|
|
424
|
+
greg.isDate = isDate;
|
|
425
|
+
/**
|
|
426
|
+
* @private
|
|
427
|
+
* @param abs - R.D. number of days
|
|
428
|
+
*/
|
|
429
|
+
function yearFromFixed(abs) {
|
|
430
|
+
const l0 = abs - 1;
|
|
431
|
+
const n400 = quotient(l0, 146097);
|
|
432
|
+
const d1 = mod$1(l0, 146097);
|
|
433
|
+
const n100 = quotient(d1, 36524);
|
|
434
|
+
const d2 = mod$1(d1, 36524);
|
|
435
|
+
const n4 = quotient(d2, 1461);
|
|
436
|
+
const d3 = mod$1(d2, 1461);
|
|
437
|
+
const n1 = quotient(d3, 365);
|
|
438
|
+
const year = 400 * n400 + 100 * n100 + 4 * n4 + n1;
|
|
439
|
+
return n100 != 4 && n1 != 4 ? year + 1 : year;
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* @private
|
|
443
|
+
* @param year
|
|
444
|
+
* @param month (1-12)
|
|
445
|
+
* @param day (1-31)
|
|
446
|
+
*/
|
|
447
|
+
function toFixed(year, month, day) {
|
|
448
|
+
const py = year - 1;
|
|
449
|
+
return 365 * py +
|
|
450
|
+
quotient(py, 4) -
|
|
451
|
+
quotient(py, 100) +
|
|
452
|
+
quotient(py, 400) +
|
|
453
|
+
quotient((367 * month - 362), 12) +
|
|
454
|
+
(month <= 2 ? 0 : (isLeapYear(year) ? -1 : -2)) +
|
|
455
|
+
day;
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* Converts Gregorian date to absolute R.D. (Rata Die) days
|
|
459
|
+
* @param {Date} date Gregorian date
|
|
460
|
+
* @return {number}
|
|
461
|
+
*/
|
|
462
|
+
function greg2abs(date) {
|
|
463
|
+
if (!isDate(date)) {
|
|
464
|
+
throw new TypeError(`Argument not a Date: ${date}`);
|
|
465
|
+
}
|
|
466
|
+
const abs = toFixed(date.getFullYear(), date.getMonth() + 1, date.getDate());
|
|
467
|
+
/*
|
|
468
|
+
if (abs < ABS_14SEP1752 && abs > ABS_2SEP1752) {
|
|
469
|
+
throw new RangeError(`Invalid Date: ${date}`);
|
|
470
|
+
}
|
|
471
|
+
*/
|
|
472
|
+
return abs;
|
|
473
|
+
}
|
|
474
|
+
greg.greg2abs = greg2abs;
|
|
475
|
+
/**
|
|
476
|
+
* Converts from Rata Die (R.D. number) to Gregorian date.
|
|
477
|
+
* See the footnote on page 384 of ``Calendrical Calculations, Part II:
|
|
478
|
+
* Three Historical Calendars'' by E. M. Reingold, N. Dershowitz, and S. M.
|
|
479
|
+
* Clamen, Software--Practice and Experience, Volume 23, Number 4
|
|
480
|
+
* (April, 1993), pages 383-404 for an explanation.
|
|
481
|
+
* @param {number} abs - R.D. number of days
|
|
482
|
+
* @return {Date}
|
|
483
|
+
*/
|
|
484
|
+
function abs2greg(abs) {
|
|
485
|
+
if (typeof abs !== 'number') {
|
|
486
|
+
throw new TypeError(`Argument not a Number: ${abs}`);
|
|
487
|
+
}
|
|
488
|
+
abs = Math.trunc(abs);
|
|
489
|
+
/*
|
|
490
|
+
if (abs < ABS_14SEP1752 && abs > ABS_2SEP1752) {
|
|
491
|
+
throw new RangeError(`Invalid Date: ${abs}`);
|
|
492
|
+
}
|
|
493
|
+
*/
|
|
494
|
+
const year = yearFromFixed(abs);
|
|
495
|
+
const priorDays = abs - toFixed(year, 1, 1);
|
|
496
|
+
const correction = abs < toFixed(year, 3, 1) ? 0 : (isLeapYear(year) ? 1 : 2);
|
|
497
|
+
const month = quotient((12 * (priorDays + correction) + 373), 367);
|
|
498
|
+
const day = abs - toFixed(year, month, 1) + 1;
|
|
499
|
+
const dt = new Date(year, month - 1, day);
|
|
500
|
+
if (year < 100 && year >= 0) {
|
|
501
|
+
dt.setFullYear(year);
|
|
502
|
+
}
|
|
503
|
+
return dt;
|
|
504
|
+
}
|
|
505
|
+
greg.abs2greg = abs2greg;
|
|
506
|
+
})(greg || (greg = {}));
|
|
592
507
|
|
|
508
|
+
/*
|
|
509
|
+
* More minimal HDate
|
|
510
|
+
*/
|
|
593
511
|
const NISAN$4 = 1;
|
|
594
512
|
const IYYAR$1 = 2;
|
|
595
513
|
// const SIVAN = 3;
|
|
@@ -603,296 +521,486 @@ const TEVET$2 = 10;
|
|
|
603
521
|
// const SHVAT = 11;
|
|
604
522
|
const ADAR_I$2 = 12;
|
|
605
523
|
const ADAR_II$1 = 13;
|
|
606
|
-
|
|
607
524
|
/**
|
|
608
525
|
* Hebrew months of the year (NISAN=1, TISHREI=7)
|
|
609
526
|
* @readonly
|
|
610
527
|
* @enum {number}
|
|
611
528
|
*/
|
|
612
529
|
const months = {
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
530
|
+
/** Nissan / ניסן */
|
|
531
|
+
NISAN: 1,
|
|
532
|
+
/** Iyyar / אייר */
|
|
533
|
+
IYYAR: 2,
|
|
534
|
+
/** Sivan / סיון */
|
|
535
|
+
SIVAN: 3,
|
|
536
|
+
/** Tamuz (sometimes Tammuz) / תמוז */
|
|
537
|
+
TAMUZ: 4,
|
|
538
|
+
/** Av / אב */
|
|
539
|
+
AV: 5,
|
|
540
|
+
/** Elul / אלול */
|
|
541
|
+
ELUL: 6,
|
|
542
|
+
/** Tishrei / תִּשְׁרֵי */
|
|
543
|
+
TISHREI: 7,
|
|
544
|
+
/** Cheshvan / חשון */
|
|
545
|
+
CHESHVAN: 8,
|
|
546
|
+
/** Kislev / כסלו */
|
|
547
|
+
KISLEV: 9,
|
|
548
|
+
/** Tevet / טבת */
|
|
549
|
+
TEVET: 10,
|
|
550
|
+
/** Sh'vat / שבט */
|
|
551
|
+
SHVAT: 11,
|
|
552
|
+
/** Adar or Adar Rishon / אדר */
|
|
553
|
+
ADAR_I: 12,
|
|
554
|
+
/** Adar Sheini (only on leap years) / אדר ב׳ */
|
|
555
|
+
ADAR_II: 13,
|
|
639
556
|
};
|
|
640
|
-
const monthNames0 = [
|
|
641
|
-
|
|
557
|
+
const monthNames0 = [
|
|
558
|
+
'',
|
|
559
|
+
'Nisan',
|
|
560
|
+
'Iyyar',
|
|
561
|
+
'Sivan',
|
|
562
|
+
'Tamuz',
|
|
563
|
+
'Av',
|
|
564
|
+
'Elul',
|
|
565
|
+
'Tishrei',
|
|
566
|
+
'Cheshvan',
|
|
567
|
+
'Kislev',
|
|
568
|
+
'Tevet',
|
|
569
|
+
'Sh\'vat',
|
|
570
|
+
];
|
|
642
571
|
/**
|
|
643
572
|
* Transliterations of Hebrew month names.
|
|
644
573
|
* Regular years are index 0 and leap years are index 1.
|
|
645
574
|
* @private
|
|
646
575
|
*/
|
|
647
|
-
const monthNames = [
|
|
648
|
-
|
|
576
|
+
const monthNames = [
|
|
577
|
+
monthNames0.concat([
|
|
578
|
+
'Adar',
|
|
579
|
+
'Nisan',
|
|
580
|
+
]),
|
|
581
|
+
monthNames0.concat([
|
|
582
|
+
'Adar I',
|
|
583
|
+
'Adar II',
|
|
584
|
+
'Nisan',
|
|
585
|
+
]),
|
|
586
|
+
];
|
|
587
|
+
const edCache = new Map();
|
|
649
588
|
const EPOCH = -1373428;
|
|
650
589
|
// Avg year length in the cycle (19 solar years with 235 lunar months)
|
|
651
590
|
const AVG_HEBYEAR_DAYS = 365.24682220597794;
|
|
652
|
-
|
|
653
591
|
/**
|
|
654
592
|
* @private
|
|
655
|
-
* @param {any} n
|
|
656
|
-
* @param {string} name
|
|
657
593
|
*/
|
|
658
594
|
function assertNumber(n, name) {
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
595
|
+
if (typeof n !== 'number' || isNaN(n)) {
|
|
596
|
+
throw new TypeError(`invalid parameter '${name}' not a number: ${n}`);
|
|
597
|
+
}
|
|
662
598
|
}
|
|
663
|
-
|
|
664
599
|
/**
|
|
665
600
|
* Converts Hebrew date to R.D. (Rata Die) fixed days.
|
|
666
601
|
* R.D. 1 is the imaginary date Monday, January 1, 1 on the Gregorian
|
|
667
602
|
* Calendar.
|
|
668
|
-
* @private
|
|
669
603
|
* @param {number} year Hebrew year
|
|
670
604
|
* @param {number} month Hebrew month
|
|
671
605
|
* @param {number} day Hebrew date (1-30)
|
|
672
606
|
* @return {number}
|
|
673
607
|
*/
|
|
674
608
|
function hebrew2abs(year, month, day) {
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
609
|
+
assertNumber(year, 'year');
|
|
610
|
+
assertNumber(month, 'month');
|
|
611
|
+
assertNumber(day, 'day');
|
|
612
|
+
if (year < 1) {
|
|
613
|
+
throw new RangeError(`hebrew2abs: invalid year ${year}`);
|
|
614
|
+
}
|
|
615
|
+
let tempabs = day;
|
|
616
|
+
if (month < TISHREI$2) {
|
|
617
|
+
for (let m = TISHREI$2; m <= monthsInYear(year); m++) {
|
|
618
|
+
tempabs += daysInMonth(m, year);
|
|
619
|
+
}
|
|
620
|
+
for (let m = NISAN$4; m < month; m++) {
|
|
621
|
+
tempabs += daysInMonth(m, year);
|
|
622
|
+
}
|
|
688
623
|
}
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
624
|
+
else {
|
|
625
|
+
for (let m = TISHREI$2; m < month; m++) {
|
|
626
|
+
tempabs += daysInMonth(m, year);
|
|
627
|
+
}
|
|
692
628
|
}
|
|
693
|
-
|
|
694
|
-
return EPOCH + elapsedDays(year) + tempabs - 1;
|
|
629
|
+
return EPOCH + elapsedDays(year) + tempabs - 1;
|
|
695
630
|
}
|
|
696
|
-
|
|
697
631
|
/**
|
|
698
632
|
* @private
|
|
699
|
-
* @param {number} year
|
|
700
|
-
* @return {number}
|
|
701
633
|
*/
|
|
702
634
|
function newYear(year) {
|
|
703
|
-
|
|
635
|
+
return EPOCH + elapsedDays(year);
|
|
704
636
|
}
|
|
705
|
-
|
|
706
637
|
/**
|
|
707
638
|
* Converts absolute R.D. days to Hebrew date
|
|
708
|
-
* @private
|
|
709
639
|
* @param {number} abs absolute R.D. days
|
|
710
640
|
* @return {SimpleHebrewDate}
|
|
711
641
|
*/
|
|
712
642
|
function abs2hebrew(abs) {
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
yy: year,
|
|
731
|
-
mm: month,
|
|
732
|
-
dd: day
|
|
733
|
-
};
|
|
643
|
+
assertNumber(abs, 'abs');
|
|
644
|
+
abs = Math.trunc(abs);
|
|
645
|
+
if (abs <= EPOCH) {
|
|
646
|
+
throw new RangeError(`abs2hebrew: ${abs} is before epoch`);
|
|
647
|
+
}
|
|
648
|
+
// first, quickly approximate year
|
|
649
|
+
let year = Math.floor((abs - EPOCH) / AVG_HEBYEAR_DAYS);
|
|
650
|
+
while (newYear(year) <= abs) {
|
|
651
|
+
++year;
|
|
652
|
+
}
|
|
653
|
+
--year;
|
|
654
|
+
let month = abs < hebrew2abs(year, 1, 1) ? 7 : 1;
|
|
655
|
+
while (abs > hebrew2abs(year, month, daysInMonth(month, year))) {
|
|
656
|
+
++month;
|
|
657
|
+
}
|
|
658
|
+
const day = 1 + abs - hebrew2abs(year, month, 1);
|
|
659
|
+
return { yy: year, mm: month, dd: day };
|
|
734
660
|
}
|
|
735
|
-
|
|
736
661
|
/**
|
|
737
662
|
* Returns true if Hebrew year is a leap year
|
|
738
|
-
* @private
|
|
739
663
|
* @param {number} year Hebrew year
|
|
740
664
|
* @return {boolean}
|
|
741
665
|
*/
|
|
742
666
|
function isLeapYear(year) {
|
|
743
|
-
|
|
667
|
+
return (1 + year * 7) % 19 < 7;
|
|
744
668
|
}
|
|
745
|
-
|
|
746
669
|
/**
|
|
747
670
|
* Number of months in this Hebrew year (either 12 or 13 depending on leap year)
|
|
748
|
-
* @private
|
|
749
671
|
* @param {number} year Hebrew year
|
|
750
672
|
* @return {number}
|
|
751
673
|
*/
|
|
752
674
|
function monthsInYear(year) {
|
|
753
|
-
|
|
675
|
+
return 12 + +(isLeapYear(year)); // boolean is cast to 1 or 0
|
|
754
676
|
}
|
|
755
|
-
|
|
756
677
|
/**
|
|
757
678
|
* Number of days in Hebrew month in a given year (29 or 30)
|
|
758
|
-
* @private
|
|
759
679
|
* @param {number} month Hebrew month (e.g. months.TISHREI)
|
|
760
680
|
* @param {number} year Hebrew year
|
|
761
681
|
* @return {number}
|
|
762
682
|
*/
|
|
763
683
|
function daysInMonth(month, year) {
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
684
|
+
switch (month) {
|
|
685
|
+
case IYYAR$1:
|
|
686
|
+
case TAMUZ$1:
|
|
687
|
+
case ELUL$2:
|
|
688
|
+
case TEVET$2:
|
|
689
|
+
case ADAR_II$1:
|
|
690
|
+
return 29;
|
|
691
|
+
}
|
|
692
|
+
if ((month === ADAR_I$2 && !isLeapYear(year)) ||
|
|
693
|
+
(month === CHESHVAN$1 && !longCheshvan(year)) ||
|
|
694
|
+
(month === KISLEV$2 && shortKislev(year))) {
|
|
695
|
+
return 29;
|
|
696
|
+
}
|
|
697
|
+
else {
|
|
698
|
+
return 30;
|
|
699
|
+
}
|
|
777
700
|
}
|
|
778
|
-
|
|
779
701
|
/**
|
|
780
702
|
* Returns a transliterated string name of Hebrew month in year,
|
|
781
703
|
* for example 'Elul' or 'Cheshvan'.
|
|
782
|
-
* @private
|
|
783
704
|
* @param {number} month Hebrew month (e.g. months.TISHREI)
|
|
784
705
|
* @param {number} year Hebrew year
|
|
785
|
-
* @return {string}
|
|
786
706
|
*/
|
|
787
707
|
function getMonthName(month, year) {
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
708
|
+
assertNumber(month, 'month');
|
|
709
|
+
assertNumber(year, 'year');
|
|
710
|
+
if (month < 1 || month > 14) {
|
|
711
|
+
throw new TypeError(`bad month argument ${month}`);
|
|
712
|
+
}
|
|
713
|
+
return monthNames[+isLeapYear(year)][month];
|
|
794
714
|
}
|
|
795
|
-
|
|
796
715
|
/**
|
|
797
716
|
* Days from sunday prior to start of Hebrew calendar to mean
|
|
798
717
|
* conjunction of Tishrei in Hebrew YEAR
|
|
799
|
-
* @private
|
|
800
718
|
* @param {number} year Hebrew year
|
|
801
719
|
* @return {number}
|
|
802
720
|
*/
|
|
803
721
|
function elapsedDays(year) {
|
|
804
|
-
|
|
805
|
-
|
|
722
|
+
const n = edCache.get(year);
|
|
723
|
+
if (typeof n === 'number') {
|
|
724
|
+
return n;
|
|
725
|
+
}
|
|
726
|
+
const elapsed = elapsedDays0(year);
|
|
727
|
+
edCache.set(year, elapsed);
|
|
728
|
+
return elapsed;
|
|
806
729
|
}
|
|
807
|
-
|
|
808
730
|
/**
|
|
809
731
|
* Days from sunday prior to start of Hebrew calendar to mean
|
|
810
732
|
* conjunction of Tishrei in Hebrew YEAR
|
|
811
733
|
* @private
|
|
812
|
-
* @param
|
|
813
|
-
* @return {number}
|
|
734
|
+
* @param year Hebrew year
|
|
814
735
|
*/
|
|
815
736
|
function elapsedDays0(year) {
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
737
|
+
const prevYear = year - 1;
|
|
738
|
+
const mElapsed = 235 * Math.floor(prevYear / 19) + // Months in complete 19 year lunar (Metonic) cycles so far
|
|
739
|
+
12 * (prevYear % 19) + // Regular months in this cycle
|
|
740
|
+
Math.floor(((prevYear % 19) * 7 + 1) / 19); // Leap months this cycle
|
|
741
|
+
const pElapsed = 204 + 793 * (mElapsed % 1080);
|
|
742
|
+
const hElapsed = 5 +
|
|
743
|
+
12 * mElapsed +
|
|
744
|
+
793 * Math.floor(mElapsed / 1080) +
|
|
745
|
+
Math.floor(pElapsed / 1080);
|
|
746
|
+
const parts = (pElapsed % 1080) + 1080 * (hElapsed % 24);
|
|
747
|
+
const day = 1 + 29 * mElapsed + Math.floor(hElapsed / 24);
|
|
748
|
+
let altDay = day;
|
|
749
|
+
if (parts >= 19440 ||
|
|
750
|
+
(2 === day % 7 && parts >= 9924 && !isLeapYear(year)) ||
|
|
751
|
+
(1 === day % 7 && parts >= 16789 && isLeapYear(prevYear))) {
|
|
752
|
+
altDay++;
|
|
753
|
+
}
|
|
754
|
+
if (altDay % 7 === 0 || altDay % 7 === 3 || altDay % 7 === 5) {
|
|
755
|
+
return altDay + 1;
|
|
756
|
+
}
|
|
757
|
+
else {
|
|
758
|
+
return altDay;
|
|
759
|
+
}
|
|
829
760
|
}
|
|
830
|
-
|
|
831
761
|
/**
|
|
832
762
|
* Number of days in the hebrew YEAR.
|
|
833
763
|
* A common Hebrew calendar year can have a length of 353, 354 or 355 days
|
|
834
764
|
* A leap Hebrew calendar year can have a length of 383, 384 or 385 days
|
|
835
|
-
* @private
|
|
836
765
|
* @param {number} year Hebrew year
|
|
837
766
|
* @return {number}
|
|
838
767
|
*/
|
|
839
768
|
function daysInYear(year) {
|
|
840
|
-
|
|
769
|
+
return elapsedDays(year + 1) - elapsedDays(year);
|
|
841
770
|
}
|
|
842
|
-
|
|
843
771
|
/**
|
|
844
772
|
* true if Cheshvan is long in Hebrew year
|
|
845
|
-
* @private
|
|
846
773
|
* @param {number} year Hebrew year
|
|
847
774
|
* @return {boolean}
|
|
848
775
|
*/
|
|
849
776
|
function longCheshvan(year) {
|
|
850
|
-
|
|
777
|
+
return daysInYear(year) % 10 === 5;
|
|
851
778
|
}
|
|
852
|
-
|
|
853
779
|
/**
|
|
854
780
|
* true if Kislev is short in Hebrew year
|
|
855
|
-
* @private
|
|
856
781
|
* @param {number} year Hebrew year
|
|
857
782
|
* @return {boolean}
|
|
858
783
|
*/
|
|
859
784
|
function shortKislev(year) {
|
|
860
|
-
|
|
785
|
+
return daysInYear(year) % 10 === 3;
|
|
861
786
|
}
|
|
862
787
|
|
|
788
|
+
const NISAN$3 = months.NISAN;
|
|
789
|
+
const CHESHVAN = months.CHESHVAN;
|
|
790
|
+
const KISLEV$1 = months.KISLEV;
|
|
791
|
+
const TEVET$1 = months.TEVET;
|
|
792
|
+
const SHVAT = months.SHVAT;
|
|
793
|
+
const ADAR_I$1 = months.ADAR_I;
|
|
794
|
+
const ADAR_II = months.ADAR_II;
|
|
863
795
|
/**
|
|
796
|
+
* Returns true if the object is a Javascript Date
|
|
864
797
|
* @private
|
|
865
|
-
* @param {
|
|
798
|
+
* @param {Object} obj
|
|
866
799
|
*/
|
|
867
|
-
function
|
|
868
|
-
|
|
800
|
+
function isSimpleHebrewDate(obj) {
|
|
801
|
+
return typeof obj === 'object' && obj !== null &&
|
|
802
|
+
typeof obj.yy === 'number' &&
|
|
803
|
+
typeof obj.mm === 'number' &&
|
|
804
|
+
typeof obj.dd === 'number';
|
|
869
805
|
}
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
Hebcal - A Jewish Calendar Generator
|
|
873
|
-
Copyright (c) 1994-2020 Danny Sadinoff
|
|
874
|
-
Portions copyright Eyal Schachter and Michael J. Radwin
|
|
875
|
-
|
|
876
|
-
https://github.com/hebcal/hebcal-es6
|
|
877
|
-
|
|
878
|
-
This program is free software; you can redistribute it and/or
|
|
879
|
-
modify it under the terms of the GNU General Public License
|
|
880
|
-
as published by the Free Software Foundation; either version 2
|
|
881
|
-
of the License, or (at your option) any later version.
|
|
882
|
-
|
|
883
|
-
This program is distributed in the hope that it will be useful,
|
|
884
|
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
885
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
886
|
-
GNU General Public License for more details.
|
|
887
|
-
|
|
888
|
-
You should have received a copy of the GNU General Public License
|
|
889
|
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
806
|
+
/**
|
|
807
|
+
* @private
|
|
890
808
|
*/
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
809
|
+
function toSimpleHebrewDate(obj) {
|
|
810
|
+
if (isSimpleHebrewDate(obj)) {
|
|
811
|
+
return obj;
|
|
812
|
+
}
|
|
813
|
+
else if (typeof obj === 'number') {
|
|
814
|
+
return abs2hebrew(obj);
|
|
815
|
+
}
|
|
816
|
+
else if (greg.isDate(obj)) {
|
|
817
|
+
const abs = greg.greg2abs(obj);
|
|
818
|
+
return abs2hebrew(abs);
|
|
819
|
+
}
|
|
820
|
+
else {
|
|
821
|
+
throw new TypeError(`Argument not a Date: ${obj}`);
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
/**
|
|
825
|
+
* Calculates yahrzeit.
|
|
826
|
+
* `hyear` must be after original `date` of death.
|
|
827
|
+
* Returns `undefined` when requested year preceeds or is same as original year.
|
|
828
|
+
*
|
|
829
|
+
* Hebcal uses the algorithm defined in "Calendrical Calculations"
|
|
830
|
+
* by Edward M. Reingold and Nachum Dershowitz.
|
|
831
|
+
*
|
|
832
|
+
* The customary anniversary date of a death is more complicated and depends
|
|
833
|
+
* also on the character of the year in which the first anniversary occurs.
|
|
834
|
+
* There are several cases:
|
|
835
|
+
*
|
|
836
|
+
* * If the date of death is Marcheshvan 30, the anniversary in general depends
|
|
837
|
+
* on the first anniversary; if that first anniversary was not Marcheshvan 30,
|
|
838
|
+
* use the day before Kislev 1.
|
|
839
|
+
* * If the date of death is Kislev 30, the anniversary in general again depends
|
|
840
|
+
* on the first anniversary — if that was not Kislev 30, use the day before
|
|
841
|
+
* Tevet 1.
|
|
842
|
+
* * If the date of death is Adar II, the anniversary is the same day in the
|
|
843
|
+
* last month of the Hebrew year (Adar or Adar II).
|
|
844
|
+
* * If the date of death is Adar I 30, the anniversary in a Hebrew year that
|
|
845
|
+
* is not a leap year (in which Adar only has 29 days) is the last day in
|
|
846
|
+
* Shevat.
|
|
847
|
+
* * In all other cases, use the normal (that is, same month number) anniversary
|
|
848
|
+
* of the date of death. [Calendrical Calculations p. 113]
|
|
849
|
+
* @example
|
|
850
|
+
* import {getYahrzeit} from '@hebcal/hdate';
|
|
851
|
+
* const dt = new Date(2014, 2, 2); // '2014-03-02' == '30 Adar I 5774'
|
|
852
|
+
* const anniversary = getYahrzeit(5780, dt); // '2/25/2020' == '30 Sh\'vat 5780'
|
|
853
|
+
* @param {number} hyear Hebrew year
|
|
854
|
+
* @param {Date | SimpleHebrewDate | number} date Gregorian or Hebrew date of death
|
|
855
|
+
* @return {Date} anniversary occurring in `hyear`
|
|
856
|
+
*/
|
|
857
|
+
function getYahrzeit(hyear, date) {
|
|
858
|
+
const hd = getYahrzeitHD(hyear, date);
|
|
859
|
+
if (typeof hd === 'undefined') {
|
|
860
|
+
return hd;
|
|
861
|
+
}
|
|
862
|
+
return greg.abs2greg(hebrew2abs(hd.yy, hd.mm, hd.dd));
|
|
863
|
+
}
|
|
864
|
+
function getYahrzeitHD(hyear, date) {
|
|
865
|
+
let hDeath = toSimpleHebrewDate(date);
|
|
866
|
+
if (hyear <= hDeath.yy) {
|
|
867
|
+
// Hebrew year ${hyear} occurs on or before original date in ${hDeath.yy}
|
|
868
|
+
return undefined;
|
|
869
|
+
}
|
|
870
|
+
if (hDeath.mm == CHESHVAN && hDeath.dd == 30 && !longCheshvan(hDeath.yy + 1)) {
|
|
871
|
+
// If it's Heshvan 30 it depends on the first anniversary;
|
|
872
|
+
// if that was not Heshvan 30, use the day before Kislev 1.
|
|
873
|
+
hDeath = abs2hebrew(hebrew2abs(hyear, KISLEV$1, 1) - 1);
|
|
874
|
+
}
|
|
875
|
+
else if (hDeath.mm == KISLEV$1 && hDeath.dd == 30 && shortKislev(hDeath.yy + 1)) {
|
|
876
|
+
// If it's Kislev 30 it depends on the first anniversary;
|
|
877
|
+
// if that was not Kislev 30, use the day before Teveth 1.
|
|
878
|
+
hDeath = abs2hebrew(hebrew2abs(hyear, TEVET$1, 1) - 1);
|
|
879
|
+
}
|
|
880
|
+
else if (hDeath.mm == ADAR_II) {
|
|
881
|
+
// If it's Adar II, use the same day in last month of year (Adar or Adar II).
|
|
882
|
+
hDeath.mm = monthsInYear(hyear);
|
|
883
|
+
}
|
|
884
|
+
else if (hDeath.mm == ADAR_I$1 && hDeath.dd == 30 && !isLeapYear(hyear)) {
|
|
885
|
+
// If it's the 30th in Adar I and year is not a leap year
|
|
886
|
+
// (so Adar has only 29 days), use the last day in Shevat.
|
|
887
|
+
hDeath.dd = 30;
|
|
888
|
+
hDeath.mm = SHVAT;
|
|
889
|
+
}
|
|
890
|
+
// In all other cases, use the normal anniversary of the date of death.
|
|
891
|
+
// advance day to rosh chodesh if needed
|
|
892
|
+
if (hDeath.mm == CHESHVAN && hDeath.dd == 30 && !longCheshvan(hyear)) {
|
|
893
|
+
hDeath.mm = KISLEV$1;
|
|
894
|
+
hDeath.dd = 1;
|
|
895
|
+
}
|
|
896
|
+
else if (hDeath.mm == KISLEV$1 && hDeath.dd == 30 && shortKislev(hyear)) {
|
|
897
|
+
hDeath.mm = TEVET$1;
|
|
898
|
+
hDeath.dd = 1;
|
|
899
|
+
}
|
|
900
|
+
hDeath.yy = hyear;
|
|
901
|
+
return hDeath;
|
|
902
|
+
}
|
|
903
|
+
/**
|
|
904
|
+
* Calculates a birthday or anniversary (non-yahrzeit).
|
|
905
|
+
* `hyear` must be after original `date` of anniversary.
|
|
906
|
+
* Returns `undefined` when requested year preceeds or is same as original year.
|
|
907
|
+
*
|
|
908
|
+
* Hebcal uses the algorithm defined in "Calendrical Calculations"
|
|
909
|
+
* by Edward M. Reingold and Nachum Dershowitz.
|
|
910
|
+
*
|
|
911
|
+
* The birthday of someone born in Adar of an ordinary year or Adar II of
|
|
912
|
+
* a leap year is also always in the last month of the year, be that Adar
|
|
913
|
+
* or Adar II. The birthday in an ordinary year of someone born during the
|
|
914
|
+
* first 29 days of Adar I in a leap year is on the corresponding day of Adar;
|
|
915
|
+
* in a leap year, the birthday occurs in Adar I, as expected.
|
|
916
|
+
*
|
|
917
|
+
* Someone born on the thirtieth day of Marcheshvan, Kislev, or Adar I
|
|
918
|
+
* has his birthday postponed until the first of the following month in
|
|
919
|
+
* years where that day does not occur. [Calendrical Calculations p. 111]
|
|
920
|
+
* @example
|
|
921
|
+
* import {getBirthdayOrAnniversary} from '@hebcal/hdate';
|
|
922
|
+
* const dt = new Date(2014, 2, 2); // '2014-03-02' == '30 Adar I 5774'
|
|
923
|
+
* const anniversary = getBirthdayOrAnniversary(5780, dt); // '3/26/2020' == '1 Nisan 5780'
|
|
924
|
+
* @param {number} hyear Hebrew year
|
|
925
|
+
* @param {Date | SimpleHebrewDate | number} date Gregorian or Hebrew date of event
|
|
926
|
+
* @return {Date} anniversary occurring in `hyear`
|
|
927
|
+
*/
|
|
928
|
+
function getBirthdayOrAnniversary(hyear, date) {
|
|
929
|
+
const hd = getBirthdayHD(hyear, date);
|
|
930
|
+
if (typeof hd === 'undefined') {
|
|
931
|
+
return hd;
|
|
932
|
+
}
|
|
933
|
+
return greg.abs2greg(hebrew2abs(hd.yy, hd.mm, hd.dd));
|
|
934
|
+
}
|
|
935
|
+
function getBirthdayHD(hyear, date) {
|
|
936
|
+
const orig = toSimpleHebrewDate(date);
|
|
937
|
+
const origYear = orig.yy;
|
|
938
|
+
if (hyear === origYear) {
|
|
939
|
+
return orig;
|
|
940
|
+
}
|
|
941
|
+
else if (hyear < origYear) {
|
|
942
|
+
// Hebrew year ${hyear} occurs on or before original date in ${origYear}
|
|
943
|
+
return undefined;
|
|
944
|
+
}
|
|
945
|
+
const isOrigLeap = isLeapYear(origYear);
|
|
946
|
+
let month = orig.mm;
|
|
947
|
+
let day = orig.dd;
|
|
948
|
+
if ((month == ADAR_I$1 && !isOrigLeap) || (month == ADAR_II && isOrigLeap)) {
|
|
949
|
+
month = monthsInYear(hyear);
|
|
950
|
+
}
|
|
951
|
+
else if (month == CHESHVAN && day == 30 && !longCheshvan(hyear)) {
|
|
952
|
+
month = KISLEV$1;
|
|
953
|
+
day = 1;
|
|
954
|
+
}
|
|
955
|
+
else if (month == KISLEV$1 && day == 30 && shortKislev(hyear)) {
|
|
956
|
+
month = TEVET$1;
|
|
957
|
+
day = 1;
|
|
958
|
+
}
|
|
959
|
+
else if (month == ADAR_I$1 && day == 30 && isOrigLeap && !isLeapYear(hyear)) {
|
|
960
|
+
month = NISAN$3;
|
|
961
|
+
day = 1;
|
|
962
|
+
}
|
|
963
|
+
return { yy: hyear, mm: month, dd: day };
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
/**
|
|
967
|
+
* @private
|
|
968
|
+
* @param {string} msg
|
|
969
|
+
*/
|
|
970
|
+
function throwTypeError(msg) {
|
|
971
|
+
throw new TypeError(msg);
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
/*
|
|
975
|
+
Hebcal - A Jewish Calendar Generator
|
|
976
|
+
Copyright (c) 1994-2020 Danny Sadinoff
|
|
977
|
+
Portions copyright Eyal Schachter and Michael J. Radwin
|
|
978
|
+
|
|
979
|
+
https://github.com/hebcal/hebcal-es6
|
|
980
|
+
|
|
981
|
+
This program is free software; you can redistribute it and/or
|
|
982
|
+
modify it under the terms of the GNU General Public License
|
|
983
|
+
as published by the Free Software Foundation; either version 2
|
|
984
|
+
of the License, or (at your option) any later version.
|
|
985
|
+
|
|
986
|
+
This program is distributed in the hope that it will be useful,
|
|
987
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
988
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
989
|
+
GNU General Public License for more details.
|
|
990
|
+
|
|
991
|
+
You should have received a copy of the GNU General Public License
|
|
992
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
993
|
+
*/
|
|
994
|
+
|
|
995
|
+
// eslint-disable-next-line require-jsdoc
|
|
996
|
+
function mod(x, y) {
|
|
997
|
+
return x - y * Math.floor(x / y);
|
|
998
|
+
}
|
|
999
|
+
const UNITS_DAY = 'day';
|
|
1000
|
+
const UNITS_WEEK = 'week';
|
|
1001
|
+
const UNITS_MONTH = 'month';
|
|
1002
|
+
const UNITS_YEAR = 'year';
|
|
1003
|
+
const UNITS_SINGLE = {
|
|
896
1004
|
d: UNITS_DAY,
|
|
897
1005
|
w: UNITS_WEEK,
|
|
898
1006
|
M: UNITS_MONTH,
|
|
@@ -978,7 +1086,7 @@ class HDate {
|
|
|
978
1086
|
day = new Date();
|
|
979
1087
|
}
|
|
980
1088
|
// 1 argument
|
|
981
|
-
const abs0 = typeof day === 'number' && !isNaN(day) ? day : isDate(day) ? greg2abs(day) : HDate.isHDate(day) ? {
|
|
1089
|
+
const abs0 = typeof day === 'number' && !isNaN(day) ? day : greg.isDate(day) ? greg.greg2abs(day) : HDate.isHDate(day) ? {
|
|
982
1090
|
dd: day.day,
|
|
983
1091
|
mm: day.month,
|
|
984
1092
|
yy: day.year
|
|
@@ -1067,19 +1175,6 @@ class HDate {
|
|
|
1067
1175
|
return mod(this.abs(), 7);
|
|
1068
1176
|
}
|
|
1069
1177
|
|
|
1070
|
-
/**
|
|
1071
|
-
* Sets the year of the date. Returns the object it was called upon.
|
|
1072
|
-
* @private
|
|
1073
|
-
* @deprecated
|
|
1074
|
-
* @param {number} year
|
|
1075
|
-
* @return {HDate}
|
|
1076
|
-
*/
|
|
1077
|
-
setFullYear(year) {
|
|
1078
|
-
this.year = year;
|
|
1079
|
-
fix(this);
|
|
1080
|
-
return this;
|
|
1081
|
-
}
|
|
1082
|
-
|
|
1083
1178
|
/**
|
|
1084
1179
|
* Sets the day of the month of the date. Returns the object it was called upon
|
|
1085
1180
|
* @private
|
|
@@ -1108,7 +1203,7 @@ class HDate {
|
|
|
1108
1203
|
* @return {Date}
|
|
1109
1204
|
*/
|
|
1110
1205
|
greg() {
|
|
1111
|
-
return abs2greg(this.abs());
|
|
1206
|
+
return greg.abs2greg(this.abs());
|
|
1112
1207
|
}
|
|
1113
1208
|
|
|
1114
1209
|
/**
|
|
@@ -1923,14 +2018,6 @@ class Event {
|
|
|
1923
2018
|
observedIn(il) {
|
|
1924
2019
|
return il ? this.observedInIsrael() : this.observedInDiaspora();
|
|
1925
2020
|
}
|
|
1926
|
-
/**
|
|
1927
|
-
* @deprecated
|
|
1928
|
-
* Optional additional event attributes (e.g. `eventTimeStr`, `cholHaMoedDay`)
|
|
1929
|
-
* @return {Object}
|
|
1930
|
-
*/
|
|
1931
|
-
getAttrs() {
|
|
1932
|
-
return this;
|
|
1933
|
-
}
|
|
1934
2021
|
/**
|
|
1935
2022
|
* Makes a clone of this Event object
|
|
1936
2023
|
* @return {Event}
|
|
@@ -2023,372 +2110,1422 @@ class HebrewDateEvent extends Event {
|
|
|
2023
2110
|
return hd.render(locale0, false);
|
|
2024
2111
|
}
|
|
2025
2112
|
}
|
|
2026
|
-
/**
|
|
2027
|
-
* Helper function to render a Hebrew date
|
|
2028
|
-
* @deprecated
|
|
2029
|
-
* @param {number} day
|
|
2030
|
-
* @param {string} monthName
|
|
2031
|
-
* @param {number} fullYear
|
|
2032
|
-
* @return {string}
|
|
2033
|
-
*/
|
|
2034
|
-
static renderHebrew(day, monthName, fullYear) {
|
|
2035
|
-
return gematriya(day) + ' ' + monthName + ' ' + gematriya(fullYear);
|
|
2036
|
-
}
|
|
2037
|
-
}
|
|
2038
|
-
|
|
2039
|
-
class Sun {
|
|
2040
|
-
constructor(date, latitude, longitude) {
|
|
2041
|
-
this.date = date;
|
|
2042
|
-
this.latitude = latitude;
|
|
2043
|
-
this.longitude = longitude;
|
|
2044
|
-
|
|
2045
|
-
this.julianDate = getJD(date);
|
|
2046
|
-
}
|
|
2047
|
-
|
|
2048
|
-
get solarNoon() {
|
|
2049
|
-
return calcSolNoon(this.julianDate, this.longitude, this.date);
|
|
2050
|
-
}
|
|
2051
|
-
|
|
2052
|
-
timeAtAngle(angle, rising) {
|
|
2053
|
-
return calcSunriseSet(rising, angle, this.julianDate, this.date, this.latitude, this.longitude);
|
|
2054
|
-
}
|
|
2055
|
-
}
|
|
2056
|
-
|
|
2057
|
-
function formatDate(date, minutes) {
|
|
2058
|
-
const seconds = (minutes - Math.floor(minutes)) * 60;
|
|
2059
|
-
return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), 0, minutes, seconds));
|
|
2060
|
-
}
|
|
2061
|
-
|
|
2062
|
-
function calcTimeJulianCent(jd) {
|
|
2063
|
-
const T = (jd - 2451545.0) / 36525.0;
|
|
2064
|
-
return T;
|
|
2065
|
-
}
|
|
2066
|
-
|
|
2067
|
-
function radToDeg(angleRad) {
|
|
2068
|
-
return (180.0 * angleRad / Math.PI);
|
|
2069
|
-
}
|
|
2070
|
-
|
|
2071
|
-
function degToRad(angleDeg) {
|
|
2072
|
-
return (Math.PI * angleDeg / 180.0);
|
|
2073
|
-
}
|
|
2074
|
-
|
|
2075
|
-
function calcGeomMeanLongSun(t) {
|
|
2076
|
-
let L0 = 280.46646 + t * (36000.76983 + t * (0.0003032));
|
|
2077
|
-
while (L0 > 360.0) {
|
|
2078
|
-
L0 -= 360.0;
|
|
2079
|
-
}
|
|
2080
|
-
while (L0 < 0.0) {
|
|
2081
|
-
L0 += 360.0;
|
|
2082
|
-
}
|
|
2083
|
-
return L0; // in degrees
|
|
2084
|
-
}
|
|
2085
|
-
|
|
2086
|
-
function calcGeomMeanAnomalySun(t) {
|
|
2087
|
-
const M = 357.52911 + t * (35999.05029 - 0.0001537 * t);
|
|
2088
|
-
return M; // in degrees
|
|
2089
|
-
}
|
|
2090
|
-
|
|
2091
|
-
function calcEccentricityEarthOrbit(t) {
|
|
2092
|
-
const e = 0.016708634 - t * (0.000042037 + 0.0000001267 * t);
|
|
2093
|
-
return e; // unitless
|
|
2094
|
-
}
|
|
2095
|
-
|
|
2096
|
-
function calcSunEqOfCenter(t) {
|
|
2097
|
-
const m = calcGeomMeanAnomalySun(t);
|
|
2098
|
-
const mrad = degToRad(m);
|
|
2099
|
-
const sinm = Math.sin(mrad);
|
|
2100
|
-
const sin2m = Math.sin(mrad + mrad);
|
|
2101
|
-
const sin3m = Math.sin(mrad + mrad + mrad);
|
|
2102
|
-
const C = sinm * (1.914602 - t * (0.004817 + 0.000014 * t)) + sin2m * (0.019993 - 0.000101 * t) + sin3m * 0.000289;
|
|
2103
|
-
return C; // in degrees
|
|
2104
|
-
}
|
|
2105
|
-
|
|
2106
|
-
function calcSunTrueLong(t) {
|
|
2107
|
-
const l0 = calcGeomMeanLongSun(t);
|
|
2108
|
-
const c = calcSunEqOfCenter(t);
|
|
2109
|
-
const O = l0 + c;
|
|
2110
|
-
return O; // in degrees
|
|
2111
2113
|
}
|
|
2112
2114
|
|
|
2113
|
-
function calcSunApparentLong(t) {
|
|
2114
|
-
const o = calcSunTrueLong(t);
|
|
2115
|
-
const omega = 125.04 - 1934.136 * t;
|
|
2116
|
-
const lambda = o - 0.00569 - 0.00478 * Math.sin(degToRad(omega));
|
|
2117
|
-
return lambda; // in degrees
|
|
2118
|
-
}
|
|
2119
|
-
|
|
2120
|
-
function calcMeanObliquityOfEcliptic(t) {
|
|
2121
|
-
const seconds = 21.448 - t * (46.8150 + t * (0.00059 - t * (0.001813)));
|
|
2122
|
-
const e0 = 23.0 + (26.0 + (seconds / 60.0)) / 60.0;
|
|
2123
|
-
return e0; // in degrees
|
|
2124
|
-
}
|
|
2125
|
-
|
|
2126
|
-
function calcObliquityCorrection(t) {
|
|
2127
|
-
const e0 = calcMeanObliquityOfEcliptic(t);
|
|
2128
|
-
const omega = 125.04 - 1934.136 * t;
|
|
2129
|
-
const e = e0 + 0.00256 * Math.cos(degToRad(omega));
|
|
2130
|
-
return e; // in degrees
|
|
2131
|
-
}
|
|
2132
|
-
|
|
2133
|
-
function calcSunDeclination(t) {
|
|
2134
|
-
const e = calcObliquityCorrection(t);
|
|
2135
|
-
const lambda = calcSunApparentLong(t);
|
|
2136
|
-
|
|
2137
|
-
const sint = Math.sin(degToRad(e)) * Math.sin(degToRad(lambda));
|
|
2138
|
-
const theta = radToDeg(Math.asin(sint));
|
|
2139
|
-
return theta; // in degrees
|
|
2140
|
-
}
|
|
2115
|
+
const n=36e11,t=864e11,e=[1,1e3,1e6,1e9,6e10,n,t],o=[9,6,3];function r(n){return n<=6}function i(n){return n>=6}const s$1=a("overflow",{constrain:0,reject:1},0);function a(n,t,e){const o=function(n,t,e){return (o,r)=>{if(void 0===o){const t=null!=r?r:e;if(void 0===t)throw new RangeError(`Must specify a ${n}`);return t}if(void 0===t[o])throw new RangeError(`Invalid ${n}: ${o}`);return t[o]}}(n,t,e);return (t,e)=>{const r=d(t);return o(r[n],e)}}function c(n,t,e,o){if(void 0===n)return t;if(!Number.isFinite(n))throw new RangeError("Number must be finite");n=Math.trunc(n);const r=Math.min(Math.max(n,t),e);if(r!==n&&1===o)throw new RangeError("Invalid overflowed value "+n);return r}function u(n,t){const e={};for(const o in t)void 0!==n[o]&&(e[o]=t[o](n[o]));return e}function d(n,t){if(void 0===n&&!t)return {};if(!h(n))throw TypeError("options must be an object or undefined");return n}const l=/object|function/;function h(n){return null!==n&&l.test(typeof n)}const f=a("roundingMode",{halfExpand:Math.round,ceil:Math.ceil,trunc:Math.trunc,floor:Math.floor});function m(){const n=new WeakMap;return [n.get.bind(n),n.set.bind(n)]}function g(n,t){Object.defineProperties(n.prototype,y(t,(n=>({get:n}))));}function y(n,t){const e={};for(const o in n)e[o]=t(n[o],o);return e}function w(n,t,e){const o={};for(const r of t)o[r]=e(n[r]);return o}function p(n,t){const e={};return n.forEach(((n,o)=>{e[n]=t(n,o);})),e}const v=["nanosecond","microsecond","millisecond","second","minute","hour"],M=[...v,"day","week","month","year"],b=M.map((n=>n+"s")),S=p(M,((n,t)=>t)),I=p(b,((n,t)=>t));function F(n,t,e,o){var r;let i;if(void 0===n){if(void 0===t)throw new RangeError("Unit is required");i=t;}else if(i=null!=(r=S[n])?r:I[n],void 0===i||i<e||i>o)throw new RangeError("Invalid unit "+n);return i}function O(n,t,o,r,i,s){var a;const c=d(n),u=null!=(a=c.roundingIncrement)?a:1,l=F(c.smallestUnit,o,r,i),h=f(c,s?Math.round:Math.trunc);let m=c.largestUnit;"auto"===m&&(m=void 0);const g=F(m,t=Math.max(t,l),r,i);if(l>g)throw new RangeError("Bad smallestUnit/largestUnit");if(l<6){const n=e[l+1],t=e[l]*u;if(n===t)throw new RangeError("Must not equal larger unit");if(n%t)throw new RangeError("Must divide into larger unit")}return {smallestUnit:l,largestUnit:g,roundingFunc:h,roundingIncrement:u}}function T(n,o,r,i){var s;const a=d("string"==typeof n?{smallestUnit:n}:n,!0),c=null!=(s=a.roundingIncrement)?s:1,u=F(a.smallestUnit,void 0,o,r),l=f(a,Math.round),h=e[u]*c;if(6===u){if(1!==c)throw new RangeError("When smallestUnit is days, roundingIncrement must be 1")}else {const n=i?t:e[u+1];if(!i&&n===h)throw new RangeError("Must not equal larger unit");if(n%h)throw new RangeError("Must divide into larger unit")}return {smallestUnit:u,roundingFunc:l,incNano:h}}const D$1=Symbol();function N(n,t,...e){return t instanceof n?t:n.from(t,...e)}class Y{toJSON(){return this.toString()}}class E extends Y{valueOf(){throw new Error("Cannot convert object using valueOf")}}const[Z,C]=m();class U extends E{constructor(n){super(),C(this,Object.freeze(n));}getISOFields(){return Z(this)}}function P(n,t){return n<t?-1:n>t?1:0}function R(n){return P(n,0)}function k(n,t,e){return e(n/t)*t}function x(n){return k(n,6e10,j)}function j(n){return Math.round(Math.abs(n))*R(n)}function q(n,t,e){const o=n.div(t).mult(t),r=n.sub(o).toNumber();return o.add(e(r/t)*t)}function H(n,t){return (n%t+t)%t}function L(n,t){return $(e=String(n),t,"0")+e;var e;}function B(n,t,e){return n+$(n,t,e)}function $(n,t,e){return new Array(Math.max(0,t-n.length+1)).join(e)}function A(n){return n<0?"-":"+"}const z=Math.pow(10,8);class W{constructor(n,t){this.high=n,this.low=t;}sign(){return R(this.high)||R(this.low)}neg(){return new W(-this.high||0,-this.low||0)}abs(){return this.sign()<0?this.neg():this}add(n){const[t,e]=J(n);return Q(this.high+t,this.low+e)}sub(n){const[t,e]=J(n);return Q(this.high-t,this.low-e)}mult(n){return Q(this.high*n,this.low*n)}div(n){const t=this.high/n;let e=String(t);-1!==e.indexOf("e-")&&(e=t.toFixed(20));const o=e.indexOf(".");let r=0;if(-1!==o){let n=e.substr(o+1);n=B(n,8,"0"),n=n.substr(0,8),r=parseInt(n)*(R(t)||1);}return Q(Math.trunc(t)||0,Math.trunc(this.low/n)+r)}toNumber(){return this.high*z+this.low}toBigInt(){return BigInt(this.high)*BigInt(z)+BigInt(this.low)}}function K(n,t){let e,o;if(n instanceof W)e=n.high,o=n.low;else if("number"==typeof n){if(t)throw new TypeError("Must supply bigint, not number");e=Math.trunc(n/z),o=n%z||0;}else if("bigint"==typeof n){const t=BigInt(z);e=Number(n/t),o=Number(n%t||0);}else {if("string"!=typeof n)throw new Error("Invalid type of BigNano");{if((n=n.trim()).match(/\D/))throw new SyntaxError(`Cannot parse ${n} to a BigInt`);const t=n.length-8;e=Number(n.substr(t)),o=Number(n.substr(0,t));}}return new W(e,o)}function G(n,t){return P(n.high,t.high)||P(n.low,t.low)}function J(n){return "number"==typeof n?[0,n]:[n.high,n.low]}function Q(n,t){let e=t%z||0,o=n+Math.trunc(t/z);const r=R(o),i=R(e);return i&&r&&i!==r&&(o+=i,e-=z*i),new W(o,e)}const V=b.concat("sign");function X(n){return w(n,V,(n=>-n||0))}function _(n,t){var e,o,r,i,s,a,c,u,d,l;return nn({years:null!=(e=t.years)?e:n.years,months:null!=(o=t.months)?o:n.months,weeks:null!=(r=t.weeks)?r:n.weeks,days:null!=(i=t.days)?i:n.days,hours:null!=(s=t.hours)?s:n.hours,minutes:null!=(a=t.minutes)?a:n.minutes,seconds:null!=(c=t.seconds)?c:n.seconds,milliseconds:null!=(u=t.milliseconds)?u:n.milliseconds,microseconds:null!=(d=t.microseconds)?d:n.microseconds,nanoseconds:null!=(l=t.nanoseconds)?l:n.nanoseconds})}function nn(n){return {...n,sign:tn(n)}}function tn(n){let t=0;for(const e of b){if(n[e]){t=R(n[e]);break}}return t}function en(n){let t=9;for(;t>0&&!n[b[t]];)t--;return t}const on={isoHour:0,isoMinute:0,isoSecond:0,isoMillisecond:0,isoMicrosecond:0,isoNanosecond:0},rn={hours:0,minutes:0,seconds:0,milliseconds:0,microseconds:0,nanoseconds:0};function sn(n){return {isoHour:n.hour||0,isoMinute:n.minute||0,isoSecond:n.second||0,isoMillisecond:n.millisecond||0,isoMicrosecond:n.microsecond||0,isoNanosecond:n.nanosecond||0}}function an(n){return K(t).mult(n.days).add(cn(n))}function cn(t){return K(t.nanoseconds).add(K(t.microseconds).mult(1e3)).add(K(t.milliseconds).mult(1e6)).add(K(t.seconds).mult(1e9)).add(K(t.minutes).mult(6e10)).add(K(t.hours).mult(n))}function un(t){return t.isoHour*n+6e10*t.isoMinute+1e9*t.isoSecond+1e6*t.isoMillisecond+1e3*t.isoMicrosecond+t.isoNanosecond}function dn(e,o){let r,i=0,s=0,a=0,c=0,u=0,d=0;switch(o){case 6:r=e.div(t),i=r.toNumber(),e=e.sub(r.mult(t));case 5:r=e.div(n),s=r.toNumber(),e=e.sub(r.mult(n));case 4:r=e.div(6e10),a=r.toNumber(),e=e.sub(r.mult(6e10));case 3:r=e.div(1e9),c=r.toNumber(),e=e.sub(r.mult(1e9));case 2:r=e.div(1e6),u=r.toNumber(),e=e.sub(r.mult(1e6));case 1:r=e.div(1e3),d=r.toNumber(),e=e.sub(r.mult(1e3));}return nn({years:0,months:0,weeks:0,days:i,hours:s,minutes:a,seconds:c,milliseconds:u,microseconds:d,nanoseconds:e.toNumber()})}function ln(e){const o=Math.floor(e/t);e-=o*t;const r=Math.floor(e/n);e-=r*n;const i=Math.floor(e/6e10);e-=6e10*i;const s=Math.floor(e/1e9);e-=1e9*s;const a=Math.floor(e/1e6);e-=1e6*a;const c=Math.floor(e/1e3);return [{isoHour:r,isoMinute:i,isoSecond:s,isoMillisecond:a,isoMicrosecond:c,isoNanosecond:e-=1e3*c},o]}const hn={gregory:{bce:-1,ce:0},ethioaa:{era0:0},ethiopic:{era0:0,era1:5500},coptic:{era0:-1,era1:0},roc:{beforeroc:-1,minguo:0},buddhist:{be:0},islamic:{ah:0},indian:{saka:0},persian:{ap:0},japanese:{bce:-1,ce:0,meiji:1867,taisho:1911,showa:1925,heisei:1988,reiwa:2018}};class fn{constructor(n){this.id=n;}monthCode(n,t){return "M"+L(n,2)}convertMonthCode(n,t){const e=/L$/.test(n),o=parseInt(n.substr(1));if(e)throw new RangeError("Calendar system doesnt support leap months");return [o,!1]}}function mn(n,t,e,o){var r;let i=null==(r=hn[gn(n)])?void 0:r[e];if(void 0===i){if(!o)throw new Error("Unkown era "+e);i=0;}return (i+t)*(R(i)||1)}function gn(n){return n.split("-")[0]}class yn extends fn{computeFields(n){const t=Fn(n);return {era:void 0,eraYear:void 0,year:t.isoYear,month:t.isoMonth,day:t.isoDay}}epochMilliseconds(n,t,e){return Sn(n,t,e)}daysInMonth(n,t){return 2===t?this.inLeapYear(n)?29:28:4===t||6===t||9===t||11===t?30:31}monthsInYear(){return 12}inLeapYear(n){return n%4==0&&(n%100!=0||n%400==0)}guessYearForMonthDay(){return pn}normalizeISOYearForMonthDay(){return pn}}const wn=new yn("iso8601"),pn=1972,vn=Symbol();function Mn(n){return bn(n.isoYear,n.isoMonth,n.isoDay,n.isoHour,n.isoMinute,n.isoSecond,n.isoMillisecond,n.isoMicrosecond,n.isoNanosecond)}function bn(n,t,e,o,r,i,s,a,c){return K(Sn(n,t,e,o,r,i,s)).mult(1e6).add(1e3*(null!=a?a:0)+(null!=c?c:0))}function Sn(n,t,e,o,r,i,s){const a=R(n);let c,u,d=0;const l=n>=0&&n<1e3,h=l?n+1200:n;for(;d<31;d++){c=e-a*d;const n=Date.UTC(h,t-1,c,null!=o?o:0,null!=r?r:0,null!=i?i:0,null!=s?s:0);if(!En(n)){u=n+a*d*864e5;break}}return (void 0===u||c<1||c>wn.daysInMonth(n,t))&&Zn(),l&&(u=new Date(u).setUTCFullYear(n)),u}function In(n){let t=n.div(1e6),e=n.sub(t.mult(1e6)).toNumber();e<0&&(e+=1e6,t=t.sub(1));const o=Math.floor(e/1e3);return e-=1e3*o,{...Fn(t.toNumber()),isoMicrosecond:o,isoNanosecond:e}}function Fn(n){const[t,e]=Yn(n);return {isoYear:t.getUTCFullYear(),isoMonth:t.getUTCMonth()+1,isoDay:t.getUTCDate()+e,isoHour:t.getUTCHours(),isoMinute:t.getUTCMinutes(),isoSecond:t.getUTCSeconds(),isoMillisecond:t.getUTCMilliseconds()}}function On(n){var t;return null!=(t=n[vn])?t:Mn(n.getISOFields())}function Tn(n){return Math.floor(Sn(n,1,1)/1e3)}function Dn(n){return Yn(n.div(1e6).toNumber())[0].getUTCFullYear()}function Nn(n,t,e){const[o,r]=Yn(Sn(n,t,e));return H(o.getUTCDay()+r,7)||7}function Yn(n){const t=R(n);let e,o=0;for(;o<31;o++){const r=new Date(n-t*o*864e5);if(!En(r)){e=r;break}}return void 0===e&&Zn(),[e,t*o]}function En(n){return isNaN(n.valueOf())}function Zn(){throw new RangeError("Date outside of supported range")}function Cn(n,t){return Math.round((t-n)/864e5)}function Un(n,t){return n+864e5*t}function Pn(n,t){return !Rn(n,t)&&n.calendar.toString()===t.calendar.toString()}function Rn(n,t){return G(Mn(n.getISOFields()),Mn(t.getISOFields()))}function kn(n,t){return P(un(n.getISOFields()),un(t.getISOFields()))}function xn(n,t){return P(n.year,t.year)||P(n.month,t.month)||P(n.day,t.day)}function jn(n,t){return G(n[vn],t[vn])}function qn(n,t,e,o,r){return [n=Number(n),t=c(t,1,o.monthsInYear(n),r),e=c(e,1,o.daysInMonth(n,t),r)]}function Hn(n,t){const[e,o,r]=qn(n.isoYear,n.isoMonth,n.isoDay,wn,t);return {isoYear:e,isoMonth:o,isoDay:r}}function Ln(n,t){return {...Hn(n,t),...Bn(n,t)}}function Bn({isoHour:n,isoMinute:t,isoSecond:e,isoMillisecond:o,isoMicrosecond:r,isoNanosecond:i},s){return {isoHour:n=c(n,0,23,s),isoMinute:t=c(t,0,59,s),isoSecond:e=c(e,0,59,s),isoMillisecond:o=c(o,0,999,s),isoMicrosecond:r=c(r,0,999,s),isoNanosecond:i=c(i,0,999,s)}}const $n={era:String,eraYear:Number,year:Number,month:Number,monthCode:String},An={...$n,day:Number},zn={hour:Number,minute:Number,second:Number,millisecond:Number,microsecond:Number,nanosecond:Number},Wn={era:String,eraYear:Number,year:Number,month:Number,monthCode:String,day:Number},Kn=p(b,(()=>Number));class Gn extends yn{computeFields(n){const t=super.computeFields(n),{year:e}=t;return {...t,era:e<1?"bce":"ce",eraYear:e<1?-(e-1):e}}}const Jn=a("calendarName",{auto:0,never:1,always:2},0),Qn=a("disambiguation",{compatible:0,earlier:1,later:2,reject:3},0);function Vn(n,t=4){const r=d(n),i=r.smallestUnit,s=r.fractionalSecondDigits;let a,u=0,l=1;return void 0!==i?(u=F(i,void 0,0,t),l=e[u],a=o[u]||0):void 0!==s&&"auto"!==s&&(a=c(s,0,9,1),l=Math.pow(10,9-a)),{smallestUnit:u,fractionalSecondDigits:a,roundingFunc:f(n,Math.trunc),incNano:l}}const Xn=a("timeZoneName",{auto:0,never:1},0);function _n(n,t){return nt(n)+"T"+et(n,t)}function nt(n){return tt(n)+"-"+L(n.isoDay,2)}function tt(n){const{isoYear:t}=n;return (t<1e3||t>9999?A(t)+L(Math.abs(t),6):L(t,4))+"-"+L(n.isoMonth,2)}function et(n,t){const e=[L(n.isoHour,2)];return t.smallestUnit<=4&&(e.push(L(n.isoMinute,2)),t.smallestUnit<=3&&e.push(L(n.isoSecond,2)+st(n.isoMillisecond,n.isoMicrosecond,n.isoNanosecond,t.fractionalSecondDigits)[0])),e.join(":")}function ot(n){const[t,e]=ln(Math.abs(n)),o=st(t.isoMillisecond,t.isoMicrosecond,t.isoNanosecond,void 0)[0];return A(n)+L(t.isoHour+24*e,2)+":"+L(t.isoMinute,2)+(t.isoSecond||o?":"+L(t.isoSecond,2)+o:"")}function rt(n,t){return n&&(2===t||1!==t&&"iso8601"!==n)?`[u-ca=${n}]`:""}function it(n){return n.map((([n,t,e])=>{if(e||n){return Math.abs(n).toLocaleString("fullwide",{useGrouping:!1})+t}return ""})).join("")}function st(n,t,o,r,i,s){let a=K(n).mult(1e6).add(K(t).mult(1e3)).add(o);i&&(a=q(a,void 0===r?e[s]:Math.pow(10,9-r),i));const c=a.abs(),u=c.div(1e9);let d=L(c.sub(u.mult(1e9)).toNumber(),9);return d=void 0===r?d.replace(/0+$/,""):d.substr(0,r),[d?"."+d:"",u.toNumber()*(a.sign()||1)]}function at(n){g(n,{epochNanoseconds(){return this[vn].toBigInt()},epochMicroseconds(){return this[vn].div(1e3).toBigInt()},epochMilliseconds(){return this[vn].div(1e6).toNumber()},epochSeconds(){return this[vn].div(1e9).toNumber()}});}const ct={calendar:"calendar"};for(const n of M)ct[n]="iso"+((ut=n).charAt(0).toUpperCase()+ut.slice(1));var ut;function dt(n,t=[]){g(n,p(t.concat("calendar"),(n=>function(){return this.getISOFields()[ct[n]]})));}const lt=["era","eraYear","year","month","monthCode","daysInMonth","daysInYear","monthsInYear","inLeapYear"],ht=[...lt,"day","dayOfWeek","dayOfYear","weekOfYear","daysInWeek"];function ft(n,t){g(n,p(t,(n=>function(){const t=this.calendar[n](this);return Object.defineProperty(this,n,{value:t}),t})));}function mt(n,t){(n.prototype||n)[Symbol.toStringTag]="Temporal."+t;}const gt=a("offset",{prefer:0,use:1,ignore:2,reject:3});function yt(n,e,o=0){const r=n.getPossibleInstantsFor(e);if(1===r.length)return r[0];if(3===o)throw new RangeError("Ambiguous offset");if(r.length)return r[2===o?1:0];{const r=function(n,e){const o=On(e),r=n.getOffsetNanosecondsFor(new Yr(o.sub(t)));return n.getOffsetNanosecondsFor(new Yr(o.add(t)))-r}(n,e),i=n.getPossibleInstantsFor(e.add({nanoseconds:r*(1===o?-1:1)}));return i[1===o?0:i.length-1]}}function wt({year:n,month:t,day:e},o,r,i){n+=o;const s=c(t,1,r.monthsInYear(n),i);let a=t===s?e:1;return a=c(a,1,r.daysInMonth(n,s),i),{year:n,month:s,day:a}}function pt({year:n,month:t,day:e},o,r,i){if(o){if(t+=o,o<0)for(;t<1;)t+=r.monthsInYear(--n);else {let e;for(;t>(e=r.monthsInYear(n));)t-=e,n++;}e=c(e,1,r.daysInMonth(n,t),i);}return {year:n,month:t,day:e}}function vt({isoYear:n,isoMonth:t,isoDay:e},o){if(o){let r=Sn(n,t,e);r=Un(r,o),({isoYear:n,isoMonth:t,isoDay:e}=Fn(r));}return {isoYear:n,isoMonth:t,isoDay:e}}function Mt(n,t){if(en(t)>=6)throw new RangeError("Duration cant have units >= days");return n.add(cn(t))}function bt(n,t,e=3,o){const{offsetNanoseconds:r,timeZone:i,Z:s}=n;if(void 0!==r&&2!==e){if(1===e||s)return Mn(n).sub(r);{const o=St(n,r,i,t);if(void 0!==o)return o;if(3===e)throw new RangeError("Mismatching offset/timezone")}}return yt(i,Ho(n),Qn(o))[vn]}function St(n,t,e,o){const r=e.getPossibleInstantsFor(Ho(n)),i=Mn(n),s=o?x(t):t;for(const n of r){const t=n[vn],e=i.sub(t).toNumber();if((o?x(e):e)===s)return t}}function It(n){const{timeZone:t}=n,e={...n,...on,calendar:new mr("iso8601")},o={...vt(e,1),...on,calendar:new mr("iso8601")},r=yt(t,Ho(e))[vn];return yt(t,Ho(o))[vn].sub(r).toNumber()}const Ft="(\\d{2})(:?(\\d{2})(:?(\\d{2})([.,](\\d{1,9}))?)?)?",Ot="([+-])"+Ft,Tt="(Z|"+Ot+")?(\\[([^=\\]]+)\\])?(\\[u-ca=([^\\]]+)\\])?",Dt=Pt("([+-]\\d{6}|\\d{4})-?(\\d{2})"+Tt),Nt=Pt("(--)?(\\d{2})-?(\\d{2})"+Tt),Yt=Pt("([+-]\\d{6}|\\d{4})-?(\\d{2})-?(\\d{2})([T ](\\d{2})(:?(\\d{2})(:?(\\d{2})([.,](\\d{1,9}))?)?)?)?"+Tt),Et=Pt("T?"+Ft+Tt),Zt=Pt(Ot),Ct=/^([-+])?P(\d+Y)?(\d+M)?(\d+W)?(\d+D)?(T((\d+)([.,](\d{1,9}))?H)?((\d+)([.,](\d{1,9}))?M)?((\d+)([.,](\d{1,9}))?S)?)?$/i,Ut=/\u2212/g;function Pt(n){return new RegExp(`^${n}$`,"i")}function Rt(n){return n.replace(Ut,"-")}function kt(n){const t=Lt(n);if(!t)throw _t("dateTime",n);return t}function xt(n){const t=Bt(n);if(!t)throw _t("dateTime",n);return t}function jt(n){const t=zt(n);if(void 0===t)throw _t("timeZone",n);return t}function qt(n){let t=function(n){const t=Et.exec(Rt(n));if(t)return Kt(t.slice(1))}(n);if(void 0!==t){if("T"!==n.charAt(0)){const e=$t(n)||At(n);e&&function(n){try{return Hn(n,1),!0}catch(n){return !1}}(e)&&(t=void 0);}}else t=Bt(n,!0);if(void 0===t)throw _t("time",n);return t}const Ht=/^Z$/i;function Lt(n){const t=Yt.exec(Rt(n));if(t)return function(n){const t=n[11];let e,o=!1;t&&(o=Ht.test(t),e=o?0:Gt(n.slice(12)));return {...Wt(n),timeZone:n[21],offsetNanoseconds:e,Z:o}}(t.slice(1))}function Bt(n,t,e){const o=Yt.exec(Rt(n));if(o&&(e||!Ht.test(o[12]))&&(!t||o[4]))return Wt(o.slice(1))}function $t(n){const t=Dt.exec(Rt(n));if(t)return {calendar:(e=t.slice(1))[14],isoYear:Vt(e[0]),isoMonth:Vt(e[1]),isoDay:1};var e;}function At(n){const t=Nt.exec(Rt(n));if(t)return {calendar:(e=t.slice(1))[15],isoYear:pn,isoMonth:Vt(e[1]),isoDay:Vt(e[2])};var e;}function zt(n){const t=Zt.exec(Rt(n));if(t)return Gt(t.slice(1))}function Wt(n){return {calendar:n[23],isoYear:Vt(n[0]),isoMonth:Vt(n[1]),isoDay:Vt(n[2]),...Kt(n.slice(4))}}function Kt(n){const t=Qt(n[4]);return {...ln(Jt(n[6]||""))[0],isoHour:Qt(n[0]),isoMinute:Qt(n[2]),isoSecond:60===t?59:t}}function Gt(t){return ("+"===t[0]?1:-1)*function(t){return Qt(t[0])*n+6e10*Qt(t[2])+1e9*Qt(t[4])+Jt(t[6]||"")}(t.slice(1))}function Jt(n){return parseInt(B(n,9,"0"))}function Qt(n){return parseInt(n||"0")}function Vt(n){return parseInt(n||"1")}function Xt(n){return void 0===n?void 0:parseInt(n)}function _t(n,t){throw new RangeError(`Cannot parse ${n} '${t}'`)}function ne(n){return {...n,calendar:void 0===n.calendar?gr():new mr(n.calendar)}}function te(n){return {...ne(n),timeZone:new we(n.timeZone)}}class ee{constructor(n){this.id=n;}}class oe extends ee{constructor(n,t){super(n),this.offsetNano=t;}getPossibleOffsets(){return [this.offsetNano]}getOffset(){return this.offsetNano}getTransition(){}}function re(n,t){const e={},o=n.formatToParts(t);for(const n of o)e[n.type]=n.value;return e}const ie={bc:"bce",ad:"ce"};function se(n){return n=n.toLowerCase().normalize("NFD").replace(/[^a-z0-9]/g,""),ie[n]||n}const ae=Intl.DateTimeFormat;function ce(n){return [].concat(n||[])}const ue={"Pacific/Apia":{2011:[[de(13017528e5),-36e12,-396e11],[de(13168728e5),-396e11,-36e12],[de(13252392e5),-36e12,504e11]]}};function de(n){return K(n).mult(1e6)}const le=(new Date).getUTCFullYear()+10,he=[182,91,273];class fe extends ee{constructor(n){const t=new ae("en-GB",{era:"short",year:"numeric",month:"numeric",day:"numeric",hour:"numeric",minute:"numeric",second:"numeric",timeZone:n});super(t.resolvedOptions().timeZone),this.format=t,this.yearEndOffsets={},this.transitionsInYear=ue[n]||{};}getPossibleOffsets(n){let t;const e=[this.getTransition(n,-1),this.getTransition(n.sub(1),1)].filter(Boolean);for(const o of e){const[e,r,i]=o,s=n.sub(r),a=n.sub(i);if(G(e,s)>0&&G(e,a)>0)return [r];if(!(G(e,s)<=0&&G(e,a)<=0))return r<i?[]:[r,i];t=i;}return void 0!==t?[t]:[1e9*this.getYearEndOffsetSec(Dn(n))]}getOffset(n){return 1e9*this.getOffsetForEpochSecs(n.div(1e9).toNumber())}getOffsetForEpochSecs(n){const t=re(this.format,1e3*n);let e=parseInt(t.year);"bce"===se(t.era)&&(e=-(e-1));const o=Sn(e,parseInt(t.month),parseInt(t.day),parseInt(t.hour),parseInt(t.minute),parseInt(t.second));return Math.floor(o/1e3)-n}getTransition(n,t){let e=Dn(n);if(e>le){const o=this.getTransitionFrom(e,e+t,t,n);if(o||t>0)return o;e=le;}return this.getTransitionFrom(Math.max(e,1847),t<0?1846:le,t,n)}getTransitionFrom(n,t,e,o){for(;n!==t;n+=e){let t=this.getTransitionsInYear(n);e<0&&(t=t.slice().reverse());for(const n of t)if(G(n[0],o)===e)return n}}getYearEndOffsetSec(n){const{yearEndOffsets:t}=this;return t[n]||(t[n]=this.getOffsetForEpochSecs(Tn(n+1)-1))}getTransitionsInYear(n){const{transitionsInYear:t}=this;return t[n]||(t[n]=this.computeTransitionsInYear(n))}computeTransitionsInYear(n){const t=this.getYearEndOffsetSec(n-1),e=this.getYearEndOffsetSec(n),o=Tn(n)-1,r=Tn(n+1)-1;if(t!==e)return [this.searchTransition(o,r,t,e)];const i=this.searchIsland(t,o);return void 0!==i?[this.searchTransition(o,i[0],t,i[1]),this.searchTransition(i[0],r,i[1],e)]:[]}searchTransition(n,t,e,o){for(;t-n>1;){const o=Math.floor(n+(t-n)/2);this.getOffsetForEpochSecs(o)===e?n=o:t=o;}return [K(t).mult(1e9),1e9*e,1e9*o]}searchIsland(n,t){for(const e of he){const o=t+86400*e,r=this.getOffsetForEpochSecs(o);if(r!==n)return [o,r]}}}const me={UTC:new oe("UTC",0)};const[ge,ye]=m();class we extends Y{constructor(n){if(!n)throw new RangeError("Invalid timezone ID");super(),ye(this,function(n){const e=(n=String(n)).toLocaleUpperCase();if(me[e])return me[e];const o=zt(n);if(void 0!==o){if(Math.abs(o)>t)throw new RangeError("Offset out of bounds");return new oe(ot(o),o)}return me[e]=new fe(n)}(n));}static from(n){if(h(n))return function(n){const t=n.timeZone;if(void 0===t)return n;if(h(t)&&void 0===t.timeZone)return t;return new we(t)}(n);const t=Lt(String(n));if(t){if(t.timeZone){const n=te(t);return function(n){const{offsetNanoseconds:t,timeZone:e,Z:o}=n;if(void 0!==t&&!o&&void 0===St(n,t,e,!0))throw new RangeError("Mismatching offset/timezone")}(n),n.timeZone}if(t.Z)return new we("UTC");if(void 0!==t.offsetNanoseconds)return new we(ot(t.offsetNanoseconds))}return new we(String(n))}get id(){return this.toString()}getOffsetStringFor(n){return ot(this.getOffsetNanosecondsFor(n))}getOffsetNanosecondsFor(n){const t=N(Yr,n);return ge(this).getOffset(t[vn])}getPlainDateTimeFor(n,t=gr()){const e=N(Yr,n);return Ho({...In(e[vn].add(this.getOffsetNanosecondsFor(e))),calendar:N(mr,t)})}getInstantFor(n,t){return yt(this,N(qo,n),Qn(t))}getPossibleInstantsFor(n){const t=Mn(N(qo,n).getISOFields());return ge(this).getPossibleOffsets(t).map((n=>new Yr(t.sub(n))))}getPreviousTransition(n){const t=N(Yr,n),e=ge(this).getTransition(t[vn],-1);return e?new Yr(e[0]):null}getNextTransition(n){const t=N(Yr,n),e=ge(this).getTransition(t[vn],1);return e?new Yr(e[0]):null}toString(){return ge(this).id}}function pe(n){if(void 0===n.timeZone)throw new TypeError("Must specify timeZone");return N(we,n.timeZone)}mt(we,"TimeZone");const ve=Le((function(n,t,e){const o=Ce(n,t,e);if(o)return {...o,timeZone:pe(n),offsetNanoseconds:void 0!==n.offset?jt(String(n.offset)):void 0}})),Me=Le(Ce),be=Le(Ue),Se=Le((function(n,t){const e=pr(n),o=je(n,$n,e);if(Be(o))return e.yearMonthFromFields(o,t)})),Ie=Le((function(n,t){const e=pr(n),o=je(n,Wn,e);if(Be(o))return void 0===n.year&&void 0===n.calendar&&(o.year=pn),e.monthDayFromFields(o,t)})),Fe=Le(Pe),Oe=Le((function(n,t,e,o){const r=Re(n,t,e,o),i=void 0!==t.offset;if(r||i)return {...r||n.getISOFields(),timeZone:n.timeZone,offsetNanoseconds:i?jt(String(t.offset)):n.offsetNanoseconds}}),!0),Te=Le(Re,!0),De=Le(ke,!0),Ne=Le((function(n,t,e){const o=n.calendar;if(Be(je(t,$n,o))){const r=He(n,t,$n,o);return o.yearMonthFromFields(r,e)}}),!0),Ye=Le((function(n,t,e){const o=n.calendar;if(Be(je(t,Wn,o))){const r=He(n,t,Wn,o);return o.monthDayFromFields(r,e)}}),!0),Ee=Le(xe,!0),Ze=Le((function(n){const t=u(n,Kn);if(Be(t))return t}));function Ce(n,t,e){const o=Ue(n,e),r=Pe(n,t);if(o)return {...o.getISOFields(),...r||on}}function Ue(n,t){const e=pr(n),o=je(n,An,e);if(Be(o))return e.dateFromFields(o,t)}function Pe(n,t){const e=u(n,zn);if(Be(e))return Bn(sn(e),t)}function Re(n,t,e,o){const r=ke(n,t,o),i=xe(n,t,e);if(r||i)return {...n.getISOFields(),...r?r.getISOFields():{},...i}}function ke(n,t,e){const o=n.calendar,r=je(t,An,o);if(Be(r)){const t=He(n,r,An,o);return o.dateFromFields(t,e)}}function xe(n,t,e){const o=u(t,zn);if(Be(o)){return Bn(sn((r=n,i=o,y(zn,((n,t)=>{var e;return null!=(e=i[t])?e:r[t]})))),e)}var r,i;}function je(n,t,e){let o=Object.keys(t);return o=e.fields?Array.prototype.slice.call(e.fields(o)):Object.keys(qe(e,o)),qe(n,o)}function qe(n,t){const e={};for(const o of t)void 0!==n[o]&&(e[o]=n[o]);return e}function He(n,t,e,o){const r=je(n,e,o);return o.mergeFields?o.mergeFields(r,t):yr(r,t)}function Le(n,t){return (...e)=>{if(t){const n=e[1];if(!h(n))throw new TypeError("must be object-like");if(void 0!==n.calendar)throw new TypeError("calendar not allowed");if(void 0!==n.timeZone)throw new TypeError("timeZone not allowed")}const o=n(...e);if(!o)throw new TypeError("No valid fields");return o}}function Be(n){return Object.keys(n).length>0}const $e=K(t).mult(1e8),Ae=$e.mult(-1),ze=$e.add(86399999999999),We=Ae.sub(86399999999999);function Ke(n,t){const e=Mn(n);Ge(e),cr(e,t);}function Ge(n){-1!==G(n,We)&&1!==G(n,ze)||Zn();}function Je(n,t){const e=Xe(un(n),t),[o,r]=ln(e);return {...vt(n,r),...o}}function Qe(n,t){const e=Xe(un(n),t),[o]=ln(e);return o}function Ve(n,t){const[e,o]=function(n){const t=In(n);return [bn(t.isoYear,t.isoMonth,t.isoDay),un(t)]}(n),r=Xe(o,t);return e.add(r)}function Xe(n,t){return k(n,t.incNano,t.roundingFunc)}function _e(n,t,e){return (o,r)=>{const i=io(n,r)?{}:{...n,...t};return {buildKey:ro(o,r,!1),buildFormat:function(n,t){return new ae(o,{calendar:n,timeZone:t||void 0,...i,...r,...e})},buildEpochMilli:no}}}function no(n){return n.epochMilliseconds}function to(n,t,e){return (o,r)=>{const i=io(n,r)?{}:n;return {buildKey:ro(o,r,e),buildFormat:function(n,e){return new ae(o,{calendar:n,...i,...r,...t,timeZone:e,timeZoneName:void 0})},buildEpochMilli:void 0!==r.timeZone?eo.bind(null,new we(r.timeZone)):oo}}}function eo(n,t){const e=Ho({...on,...t.getISOFields()});return n.getInstantFor(e).epochMilliseconds}function oo(n){return Sn((t=n.getISOFields()).isoYear,t.isoMonth,t.isoDay,t.isoHour,t.isoMinute,t.isoSecond,t.isoMillisecond);var t;}function ro(n,t,e){var o;const r=null!=(o=t.calendar)?o:function(n){for(const t of n){const n=t.match(/-u-ca-(.*)$/);if(n)return n[1]}return}(n),i=t.timeZone;return function(n,t){var o,s,a,c;const u=null==(o=n.calendar)?void 0:o.id,d=null==(s=n.timeZone)?void 0:s.id;if(t){if((null==(a=t.calendar)?void 0:a.id)!==u)throw new RangeError("Mismatching calendar");if((null==(c=t.timeZone)?void 0:c.id)!==d)throw new RangeError("Mismatching timeZone")}if((e||"iso8601"!==u)&&void 0!==u&&void 0!==r&&r!==u)throw new RangeError("Non-iso calendar mismatch");if(void 0!==d&&void 0!==i&&i!==d)throw new RangeError("Given timeZone must agree");return [r||u||"iso8601",i||d||"UTC"]}}function io(n,t){for(const e in n)if(void 0!==t[e])return !0;return !1}function so(n,t){n.prototype.toLocaleString=function(n,e){const o=t(ce(n),e||{});return o.buildFormat(...o.buildKey(this)).format(o.buildEpochMilli(this))},n.prototype[D$1]=t;}function co(n){const t=function(n){const t=Ct.exec(Rt(n));if(t){let n,e,o,r;[n,r]=uo(t[8],t[10],5,void 0),[e,r]=uo(t[12],t[14],4,r),[o,r]=uo(t[16],t[18],3,r);const i=function(n){const t={};for(const e in n)void 0!==n[e]&&(t[e]=n[e]);return t}({years:Xt(t[2]),months:Xt(t[3]),weeks:Xt(t[4]),days:Xt(t[5]),hours:n,minutes:e,seconds:o});if(!Object.keys(i).length)throw new RangeError("Duration string must have at least one field");const s=dn(K(r||0),2);i.milliseconds=s.milliseconds,i.microseconds=s.microseconds,i.nanoseconds=s.nanoseconds;let a=nn(i);return "-"===t[1]&&(a=X(a)),a}}(n);if(void 0===t)throw _t("duration",n);return t}function uo(n,t,o,r){if(void 0!==n){if(void 0!==r)throw new RangeError("Partial units must be last unit");return [parseInt(n),void 0!==t?Jt(t)*(e[o]/1e9):void 0]}if(void 0!==r){const n=Math.trunc(r/e[o]);return [n,r-n*e[o]]}return [void 0,void 0]}const lo=a("offset",{auto:0,never:1},0);class ho extends U{constructor(n=0,t=0,e=0,o=0,r=0,i=0){super({...Bn({isoHour:n,isoMinute:t,isoSecond:e,isoMillisecond:o,isoMicrosecond:r,isoNanosecond:i},1),calendar:gr()});}static from(n,t){const e=s$1(t);return fo(n instanceof ho?n.getISOFields():"object"==typeof n?Fe(n,e):qt(String(n)))}static compare(n,t){return kn(N(ho,n),N(ho,t))}with(n,t){return fo(Ee(this,n,s$1(t)))}add(n){return go(this,N(ko,n))}subtract(n){return go(this,X(N(ko,n)))}until(n,t){return yo(this,N(ho,n),t)}since(n,t){return yo(N(ho,n),this,t)}round(n){const t=T(n,0,5);return fo(Qe(this.getISOFields(),t))}equals(n){return !kn(this,N(ho,n))}toString(n){const t=Vn(n);return et(Qe(this.getISOFields(),t),t)}toZonedDateTime(n){const t=N(Sr,n.plainDate),e=N(we,n.timeZone);return Fo({...t.getISOFields(),...this.getISOFields(),timeZone:e})}toPlainDateTime(n){return N(Sr,n).toPlainDateTime(this)}}function fo(n){return new ho(n.isoHour,n.isoMinute,n.isoSecond,n.isoMillisecond,n.isoMicrosecond,n.isoNanosecond)}function mo(n){return N(ho,null!=n?n:{hour:0})}function go(n,t){return fo(function(n,t){const e=un(n)+cn(t).toNumber(),[o]=ln(e);return o}(n.getISOFields(),t))}function yo(n,t,o){const r=O(o,5,0,0,5);return xo(function(n,t,o){return dn(K(k(un(t)-un(n),e[o.smallestUnit]*o.roundingIncrement,o.roundingFunc)),o.largestUnit)}(n.getISOFields(),t.getISOFields(),r))}mt(ho,"PlainTime"),dt(ho,v),so(ho,(function(n,t){return {buildKey:()=>["",""],buildFormat:()=>new ae(n,{hour:"numeric",minute:"2-digit",second:"2-digit",...t,timeZone:"UTC",timeZoneName:void 0,year:void 0,month:void 0,day:void 0,weekday:void 0}),buildEpochMilli:n=>Math.trunc(un(n.getISOFields())/1e6)}}));const wo={day:1};class po extends U{constructor(n,t,e=gr(),o=1){const r=Hn({isoYear:n,isoMonth:t,isoDay:o},1),i=N(mr,e);var s,a;s=r,a=i.toString(),cr(Mn(s),a),super({...r,calendar:i});}static from(n,t){if(s$1(t),n instanceof po)return vo(n.getISOFields());if("object"==typeof n)return Se(n,t);const e=function(n){const t=$t(n)||Bt(n);if(!t)throw _t("yearMonth",n);return t}(String(n));return void 0===e.calendar&&(e.isoDay=1),vo(ne(e))}static compare(n,t){return Rn(N(po,n),N(po,t))}with(n,t){return Ne(this,n,t)}add(n,t){return Mo(this,N(ko,n),t)}subtract(n,t){return Mo(this,X(N(ko,n)),t)}until(n,t){return bo(this,N(po,n),!1,t)}since(n,t){return bo(this,N(po,n),!0,t)}equals(n){return !Rn(this,N(po,n))}toString(n){const t=this.getISOFields(),e=t.calendar.toString(),o=Jn(n);return ("iso8601"===e?tt(t):nt(t))+rt(e,o)}toPlainDate(n){return this.calendar.dateFromFields({year:this.year,month:this.month,day:n.day})}}function vo(n){return new po(n.isoYear,n.isoMonth,n.calendar,n.isoDay)}function Mo(n,t,e){return n.toPlainDate({day:t.sign<0?n.daysInMonth:1}).add(t,e).toPlainYearMonth()}function bo(n,t,e,o){return xo(Tr(n.toPlainDate(wo),t.toPlainDate(wo),vr(n,t),e,O(o,9,8,8,9)))}mt(po,"PlainYearMonth"),dt(po),ft(po,lt),so(po,to({year:"numeric",month:"numeric"},{weekday:void 0,day:void 0,hour:void 0,minute:void 0,second:void 0},!0));const So=Symbol();class Io extends U{constructor(n,t,e=gr()){const o=N(we,t),r=N(mr,e),i=K(n),[s,a]=Oo(i,o);Ke(s,r.toString()),super({...s,calendar:r,timeZone:o,offset:ot(a)}),this[vn]=i,this[So]=a;}static from(n,t){const e=gt(t,3),o=s$1(t);if(n instanceof Io)return new Io(n.epochNanoseconds,n.timeZone,n.calendar);const r="object"==typeof n;return Fo(r?ve(n,o,t):te(kt(String(n))),!r,e,t)}static compare(n,t){return jn(N(Io,n),N(Io,t))}get timeZone(){return this.getISOFields().timeZone}get offsetNanoseconds(){return this[So]}get offset(){return this.getISOFields().offset}with(n,t){Qn(t);const e=s$1(t),o=gt(t,0);return Fo(Oe(this,n,e,t),!1,o,t)}withPlainDate(n){const t=N(Sr,n),e=t.toPlainDateTime(this),{timeZone:o}=this,r=yt(o,e);return new Io(r.epochNanoseconds,o,Mr(this,t))}withPlainTime(n){return Fo({...this.getISOFields(),...void 0===n?on:N(ho,n).getISOFields()})}withCalendar(n){return new Io(this.epochNanoseconds,this.timeZone,n)}withTimeZone(n){return new Io(this.epochNanoseconds,n,this.calendar)}add(n,t){return To(this,N(ko,n),t)}subtract(n,t){return To(this,X(N(ko,n)),t)}until(n,t){return No(this,N(Io,n),!1,t)}since(n,t){return No(this,N(Io,n),!0,t)}round(n){return Do(this,T(n,0,6))}equals(n){return t=this,e=N(Io,n),Pn(t,e)&&t.timeZone.toString()===e.timeZone.toString();var t,e;}startOfDay(){return Fo({...this.getISOFields(),...on,offsetNanoseconds:this.offsetNanoseconds},!1,0)}get hoursInDay(){return It(this.getISOFields())/n}toString(n){const t=Vn(n),e=lo(n),o=Xn(n),r=Jn(n),i=Do(this,t);return _n(i.getISOFields(),t)+(0===e?ot(x(i.offsetNanoseconds)):"")+(s=this.timeZone.toString(),1!==o?`[${s}]`:"")+rt(this.calendar.toString(),r);var s;}toPlainYearMonth(){return vo(this.getISOFields())}toPlainMonthDay(){return this.calendar.monthDayFromFields(this)}toPlainDateTime(){return Ho(this.getISOFields())}toPlainDate(){return Ir(this.getISOFields())}toPlainTime(){return fo(this.getISOFields())}toInstant(){return new Yr(this.epochNanoseconds)}}function Fo(n,t,e,o){const r=bt(n,t,e,o);return new Io(r,n.timeZone,n.calendar)}function Oo(n,t){const e=new Yr(n),o=t.getOffsetNanosecondsFor(e);return [In(n.add(o)),o]}function To(n,t,e){const o=n.getISOFields(),r=function(n,t,e){const{calendar:o,timeZone:r}=n,i=o.dateAdd(Ir(n),_(t,rn),e);return yt(r,Ho({...n,...i.getISOFields()}))[vn].add(cn(t))}(o,t,e);return new Io(r,o.timeZone,o.calendar)}function Do(n,t){const e=n.getISOFields(),o=function(n,t,e){const{calendar:o,timeZone:r}=n;let i,s,a=un(n);return 6===e.smallestUnit?(i=on,s=e.roundingFunc(a/It(n))):(a=Xe(a,e),[i,s]=ln(a)),bt({...vt(n,s),...i,offsetNanoseconds:t,calendar:o,timeZone:r},!1,0)}(e,n.offsetNanoseconds,t);return new Io(o,e.timeZone,e.calendar)}function No(n,t,e,o){const r=O(o,5,0,0,9),{largestUnit:i}=r;if(i>=6&&n.timeZone.id!==t.timeZone.id)throw new Error("Must be same timeZone");return xo(Or(n,t,vr(n,t),e,r))}function Yo(n){if(void 0===n)return;if(h(n))return n instanceof Io||n instanceof qo?n:N(void 0!==n.timeZone?Io:qo,n);if("symbol"==typeof n)throw new TypeError("Incorrect relativeTo type");const t=Lt(String(n));if(t)return void 0!==t.timeZone?Fo(te(t),!0):Ho(ne(t));throw new RangeError("Invalid value of relativeTo")}function Eo(n,t,e,o){return (e instanceof Sr?function(n,t,e,o){const r=e.add(n);return [o.dateUntil(e,r,{largestUnit:M[t]}),r]}(n,Math.max(6,t),e,o):Zo(n,t,e,o))[0]}function Zo(n,t,e,o,r){const i=!0!==r&&t>7&&n.weeks;i&&(n=_(n,{weeks:0}));let s=e.add(n),a=Dr(e,s,o,t);return i&&(a=_(a,{weeks:i}),s=s.add({weeks:i})),[a,s]}function Co(n,t,e,o){const r=b[t],{sign:i}=n;if(!i)return n;const s={};for(let e=9;e>=t;e--){const t=b[e];s[t]=n[t];}const a={[r]:i},c=e.add(s),u=c.add(a),d=On(c),l=On(u),h=On(o).sub(d).toNumber()/l.sub(d).toNumber()*i;return s[r]+=h,s}function Uo(n,t,o,r,s,a){const{largestUnit:c,smallestUnit:u,roundingIncrement:d,roundingFunc:l}=a;if(!i(c)){return dn(q(On(o).sub(On(t)).mult(s?-1:1),e[u]*d,l),c)}let h=Co(n,u,t,o);const f=b[u];function m(){const n=h[f];h[f]=k(n,d,l);}return l===Math.round&&m(),s&&(h=X(h)),l!==Math.round&&m(),u>0&&(h=s?X(Eo(X(h),c,t,r)):Eo(h,c,t,r)),h}mt(Io,"ZonedDateTime"),dt(Io,v),ft(Io,ht),at(Io),so(Io,_e({year:"numeric",month:"numeric",day:"numeric",weekday:void 0,hour:"numeric",minute:"2-digit",second:"2-digit"},{timeZoneName:"short"},{}));const[Po,Ro]=m();class ko extends E{constructor(n=0,t=0,e=0,o=0,r=0,i=0,s=0,a=0,c=0,u=0){super();const d=Ze({years:n,months:t,weeks:e,days:o,hours:r,minutes:i,seconds:s,milliseconds:a,microseconds:c,nanoseconds:u});Ro(this,function(n){const t=nn(n),{sign:e}=t;for(const n of b){const o=t[n],r=R(t[n]);if(r&&r!==e)throw new RangeError("All fields must be same sign");if(!Number.isInteger(o))throw new RangeError("Duration fields must be integers")}return t}(d));}static from(n){return xo("object"==typeof n?Ze(n):co(n))}static compare(n,t,e){return function(n,t,e){if(void 0===e&&en(n)<=6&&en(t)<=6)return G(an(n),an(t));if(!e)throw new RangeError("Need relativeTo");const o=e.add(n),r=e.add(t);return void 0!==e[vn]?jn(o,r):Rn(o,r)}(N(ko,n),N(ko,t),Yo(d(e).relativeTo))}get years(){return Po(this).years}get months(){return Po(this).months}get weeks(){return Po(this).weeks}get days(){return Po(this).days}get hours(){return Po(this).hours}get minutes(){return Po(this).minutes}get seconds(){return Po(this).seconds}get milliseconds(){return Po(this).milliseconds}get microseconds(){return Po(this).microseconds}get nanoseconds(){return Po(this).nanoseconds}get sign(){return Po(this).sign}get blank(){return !this.sign}with(n){return xo({...Po(this),...Ze(n)})}negated(){return xo(X(Po(this)))}abs(){return xo(w(Po(this),V,(n=>Math.abs(n))))}add(n,t){return jo(this,N(ko,n),t)}subtract(n,t){return jo(this,X(N(ko,n)),t)}round(n){const t="string"==typeof n?{smallestUnit:n}:n;if(!h(t))throw new TypeError("Must specify options");if(void 0===t.largestUnit&&void 0===t.smallestUnit)throw new RangeError("Must specify either largestUnit or smallestUnit");const o=O(t,en(this),0,0,9,!0),i=Yo(t.relativeTo);return xo(function(n,t,o,i){const{largestUnit:s,smallestUnit:a,roundingIncrement:c,roundingFunc:u}=t;if(void 0===o&&en(n)<=6&&r(s)&&r(a))return dn(q(an(n),e[a]*c,u),s);if(!o)throw new RangeError("Need relativeTo");const[d,l]=Zo(n,s,o,i);return Uo(d,o,l,i,!1,t)}(this,o,i,i?i.calendar:void 0))}total(n){const t=function(n){let t,e;return "string"==typeof n?e=n:(e=d(n).unit,t=n.relativeTo),{unit:F(e,void 0,0,9),relativeTo:t}}(n),o=Yo(t.relativeTo);return function(n,t,o,i){if(void 0===o&&en(n)<=6&&r(t))return an(n).toNumber()/e[t];if(!o)throw new RangeError("Need relativeTo");const[s,a]=Zo(n,t,o,i,!0);return Co(s,t,o,a)[b[t]]}(this,t.unit,o,o?o.calendar:void 0)}toString(n){const t=Vn(n,3);return function(n,t){const{smallestUnit:e,fractionalSecondDigits:o,roundingFunc:r}=t,{sign:i}=n,s=n.hours,a=n.minutes;let c=n.seconds,u="";if(e<=3){const t=st(n.milliseconds,n.microseconds,n.nanoseconds,o,r,e);u=t[0],c+=t[1];}const d=void 0!==o||u||!i;return (i<0?"-":"")+"P"+it([[n.years,"Y"],[n.months,"M"],[n.weeks,"W"],[n.days,"D"]])+(s||a||c||d?"T"+it([[s,"H"],[a,"M"],[e<=3?c:0,u+"S",d]]):"")}(Po(this),t)}toLocaleString(n,t){return this.toString()}}function xo(n){return new ko(n.years,n.months,n.weeks,n.days,n.hours,n.minutes,n.seconds,n.milliseconds,n.microseconds,n.nanoseconds)}function jo(n,t,e){const o=Yo(d(e).relativeTo);return xo(function(n,t,e,o){const r=Math.max(en(n),en(t));if(void 0===e&&r<=6)return dn(an(n).add(an(t)),r);if(!e)throw new RangeError("Need relativeTo");const i=e.add(n).add(t);return Dr(e,i,o,r)}(n,t,o,o?o.calendar:void 0))}mt(ko,"Duration");class qo extends U{constructor(n,t,e,o=0,r=0,i=0,s=0,a=0,c=0,u=gr()){const d=Ln({isoYear:n,isoMonth:t,isoDay:e,isoHour:o,isoMinute:r,isoSecond:i,isoMillisecond:s,isoMicrosecond:a,isoNanosecond:c},1),l=N(mr,u);Ke(d,l.toString()),super({...d,calendar:l});}static from(n,t){const e=s$1(t);return Ho(n instanceof qo?n.getISOFields():"object"==typeof n?Me(n,e,t):ne(xt(String(n))))}static compare(n,t){return Rn(N(qo,n),N(qo,t))}with(n,t){const e=s$1(t);return Ho(Te(this,n,e,t))}withPlainDate(n){const t=N(Sr,n);return Ho({...this.getISOFields(),...t.getISOFields(),calendar:Mr(this,t)})}withPlainTime(n){return Ho({...this.getISOFields(),...mo(n).getISOFields()})}withCalendar(n){return Ho({...this.getISOFields(),calendar:N(mr,n)})}add(n,t){return Lo(this,N(ko,n),t)}subtract(n,t){return Lo(this,X(N(ko,n)),t)}until(n,t){return Bo(this,N(qo,n),!1,t)}since(n,t){return Bo(this,N(qo,n),!0,t)}round(n){const t=T(n,0,6);return Ho({...Je(this.getISOFields(),t),calendar:this.calendar})}equals(n){return Pn(this,N(qo,n))}toString(n){const t=Vn(n),e=Jn(n);return _n(Je(this.getISOFields(),t),t)+rt(this.calendar.toString(),e)}toZonedDateTime(n,t){const e=N(we,n),o=yt(e,this,Qn(t));return new Io(o.epochNanoseconds,e,this.calendar)}toPlainYearMonth(){return vo(this.getISOFields())}toPlainMonthDay(){return this.calendar.monthDayFromFields(this)}toPlainDate(){return Ir(this.getISOFields())}toPlainTime(){return fo(this.getISOFields())}}function Ho(n){return new qo(n.isoYear,n.isoMonth,n.isoDay,n.isoHour,n.isoMinute,n.isoSecond,n.isoMillisecond,n.isoMicrosecond,n.isoNanosecond,n.calendar)}function Lo(n,t,e){const o=function(n,t,e){const{calendar:o}=n;return In(Mn(o.dateAdd(Ir(n),_(t,rn),e).getISOFields()).add(un(n)).add(cn(t)))}(n.getISOFields(),t,e);return Ho({...o,calendar:n.calendar})}function Bo(n,t,e,o){const r=O(o,6,0,0,9);return xo(Or(n,t,vr(n,t),e,r))}mt(qo,"PlainDateTime"),dt(qo,v),ft(qo,ht),so(qo,to({year:"numeric",month:"numeric",day:"numeric",weekday:void 0,hour:"numeric",minute:"2-digit",second:"2-digit"},{}));class $o extends U{constructor(n,t,e=gr(),o=pn){super({...Hn({isoYear:o,isoMonth:n,isoDay:t},1),calendar:N(mr,e)});}static from(n,t){if(s$1(t),n instanceof $o)return Ao(n.getISOFields());if("object"==typeof n)return Ie(n,t);const e=function(n){const t=At(n)||Bt(n);if(!t)throw _t("monthDay",n);return t}(String(n));return void 0===e.calendar&&(e.isoYear=pn),Ao(ne(e))}with(n,t){return Ye(this,n,t)}equals(n){return !Rn(this,N($o,n))}toString(n){const t=this.getISOFields(),e=t.calendar.toString(),o=Jn(n);return ("iso8601"===e?function(n){return L(n.isoMonth,2)+"-"+L(n.isoDay,2)}(t):nt(t))+rt(e,o)}toPlainDate(n){return this.calendar.dateFromFields({year:n.year,monthCode:this.monthCode,day:this.day},{overflow:"reject"})}}function Ao(n){return new $o(n.isoMonth,n.isoDay,n.calendar,n.isoYear)}function zo(n){return n instanceof Sr||n instanceof qo||n instanceof Io||n instanceof po||n instanceof $o}function Wo(n,t,e){let o;if(n instanceof Sr)o=n;else if(zo(n)){if(e&&n instanceof $o)throw new TypeError("PlainMonthDay not allowed");o=Ir(n.getISOFields());}else o=Sr.from(n);return br(o.calendar,t),o}function Ko(n,t,e){if(zo(n))return n.getISOFields();let{era:o,eraYear:r,year:i,month:a,monthCode:c,day:u}=n;const d=void 0!==r&&void 0!==o?mn(t.id,r,o):void 0;if(void 0===i){if(void 0===d)throw new TypeError("Must specify either a year or an era & eraYear");i=d;}else if(void 0!==d&&d!==i)throw new RangeError("year and era/eraYear must match");if(void 0===u)throw new TypeError("Must specify day");const l=s$1(e);if(void 0!==c){const[n,e]=t.convertMonthCode(c,i);if(void 0!==a&&a!==n)throw new RangeError("Month doesnt match with monthCode");if(a=n,e){if(1===l)throw new RangeError("Month code out of range");u=t.daysInMonth(i,a);}}else if(void 0===a)throw new TypeError("Must specify either a month or monthCode");return [i,a,u]=qn(i,a,u,t,l),Fn(t.epochMilliseconds(i,a,u))}function Go(n,t){if(zo(n)){if(t&&n instanceof $o)throw new TypeError("PlainMonthDay not allowed");return n.getISOFields()}return Sr.from(n).getISOFields()}function Jo(n,t){return Cn(n.epochMilliseconds(t,1,1),n.epochMilliseconds(t+1,1,1))}function Qo(n,t,e,o){return Cn(n.epochMilliseconds(t,1,1),n.epochMilliseconds(t,e,o))+1}mt($o,"PlainMonthDay"),dt($o),ft($o,["monthCode","day"]),so($o,to({month:"numeric",day:"numeric"},{weekday:void 0,year:void 0,hour:void 0,minute:void 0,second:void 0},!0));const Vo={hebrew:6,chinese:0,dangi:0};class Xo extends fn{constructor(n){const t=_o(n);if(e=n,o=t.resolvedOptions().calendar,gn(e)!==gn(o))throw new RangeError("Invalid calendar: "+n);var e,o;super(n),this.format=t,this.yearCorrection=this.computeFieldsDumb(0).year-1970,this.monthCacheByYear={};}epochMilliseconds(n,t,e){return Un(this.queryMonthCache(n)[0][t-1],e-1)}daysInMonth(n,t){const e=this.queryMonthCache(n)[0],o=e[t-1];t>=e.length&&(n++,t=0);return Cn(o,this.queryMonthCache(n)[0][t])}monthsInYear(n){return this.queryMonthCache(n)[0].length}monthCode(n,t){const e=this.queryLeapMonthByYear(t);return !e||n<e?super.monthCode(n,t):super.monthCode(n-1,t)+(n===e?"L":"")}convertMonthCode(n,t){const e=this.queryLeapMonthByYear(t);let o=/L$/.test(n),r=parseInt(n.substr(1)),i=!1;if(o){const n=Vo[this.id];if(void 0===n)throw new RangeError("Calendar system doesnt support leap months");if(n){if(r!==n-1)throw new RangeError("Invalid leap-month month code")}else if(r<=1||r>=12)throw new RangeError("Invalid leap-month month code")}return !o||e&&r===e-1||(i=!0,o=!1),(o||e&&r>=e)&&r++,[r,i]}inLeapYear(n){const t=Jo(this,n);return t>Jo(this,n-1)&&t>Jo(this,n+1)}guessYearForMonthDay(n,t){let e=1970+this.yearCorrection;const o=e+100;for(;e<o;e++){const[o,r]=this.convertMonthCode(n,e);if(!r&&o<=this.monthsInYear(e)&&t<=this.daysInMonth(e,o))return e}throw new Error("Could not guess year")}normalizeISOYearForMonthDay(n){return n}computeFields(n){const t=this.computeFieldsDumb(n),e=this.queryMonthCache(t.year)[2];return {...t,month:e[t.month]}}computeFieldsDumb(n){const t=re(this.format,n);let e,o,r=parseInt(t.relatedYear||t.year);var i;return t.era&&(i=this.id,void 0!==hn[gn(i)])&&(e=se(t.era),o=r,r=mn(this.id,o,e,!0)),{era:e,eraYear:o,year:r,month:t.month,day:parseInt(t.day)}}queryLeapMonthByYear(n){const t=this.queryMonthCache(n),e=this.queryMonthCache(n-1),o=this.queryMonthCache(n+1);if(t[0].length>e[0].length&&t[0].length>o[0].length){const n=t[1],o=e[1];for(let t=0;t<o.length;t++)if(o[t]!==n[t])return t+1}}queryMonthCache(n){const{monthCacheByYear:t}=this;return t[n]||(t[n]=this.buildMonthCache(n))}buildMonthCache(n){const t=[],e=[],o={};let r=Sn(this.guessISOYear(n),1,1);for(r=Un(r,400);;){const o=this.computeFieldsDumb(r);if(o.year<n)break;r=Un(r,1-o.day),o.year===n&&(t.unshift(r),e.unshift(o.month)),r=Un(r,-1);}for(let n=0;n<e.length;n++)o[e[n]]=n+1;return [t,e,o]}guessISOYear(n){return n-this.yearCorrection}}function _o(n){return new ae("en-US",{calendar:n,era:"short",year:"numeric",month:"short",day:"numeric",timeZone:"UTC"})}const nr=Sn(1868,9,8);const tr={gregory:Gn,japanese:class extends Gn{constructor(){super(...arguments),this.format=_o("japanese");}computeFields(n){const t=super.computeFields(n);if(n>=nr){const e=re(this.format,n);t.era=se(e.era),t.eraYear=parseInt(e.relatedYear||e.year);}return t}},islamic:class extends Xo{guessISOYear(n){return Math.ceil(32*n/33+622)}}},er={iso8601:wn};function or(n){const t=(n=String(n)).toLocaleLowerCase();return er[t]||(er[t]=new(tr[gn(t)]||Xo)(n))}const rr=Sn(1582,10,15),ir=Sn(622,7,18),sr={buddhist:rr,japanese:rr,roc:rr,islamic:ir,"islamic-rgsa":ir,indian:0},ar={};function cr(n,t){return ur(n.div(1e6).toNumber(),t)}function ur(n,t){if(function(n,t){return function(n){let t=ar[n];if(void 0===t){const e=sr[n];if(void 0===e)t=!1;else {let o=or(n);o instanceof Xo||(o=new Xo(n));const r=e-864e5,i=o.computeFields(r);t=r!==o.epochMilliseconds(i.year,i.month,i.day);}ar[n]=t;}return t}(t)&&n<sr[t]}(n,t))throw new RangeError("Invalid timestamp for calendar")}function dr(n,t,e){const o=7+t-e;return -H(Nn(n,1,o)-t,7)+o-1}function lr(n,t,e){const o=dr(n,t,e),r=dr(n+1,t,e);return (Jo(wn,n)-o+r)/7}const[hr,fr]=m();class mr extends Y{constructor(n){super(),"islamicc"===n&&(n="islamic-civil"),fr(this,or(n));}static from(n){if(h(n))return function(n){const t=n.calendar;if(void 0===t)return n;if(h(t)&&void 0===t.calendar)return t;return new mr(t)}(n);const t=Bt(String(n),!1,!0);return new mr(t?t.calendar||"iso8601":String(n))}get id(){return this.toString()}era(n){const t=Go(n,!0);return wr(hr(this),t.isoYear,t.isoMonth,t.isoDay).era}eraYear(n){const t=Go(n,!0);return wr(hr(this),t.isoYear,t.isoMonth,t.isoDay).eraYear}year(n){const t=Go(n,!0);return wr(hr(this),t.isoYear,t.isoMonth,t.isoDay).year}month(n){const t=Go(n,!0);return wr(hr(this),t.isoYear,t.isoMonth,t.isoDay).month}monthCode(n){const t=Wo(n,this);return hr(this).monthCode(t.month,t.year)}day(n){const t=Go(n);return wr(hr(this),t.isoYear,t.isoMonth,t.isoDay).day}dayOfWeek(n){const t=Go(n,!0);return Nn(t.isoYear,t.isoMonth,t.isoDay)}dayOfYear(n){const t=Wo(n,this,!0);return Qo(hr(this),t.year,t.month,t.day)}weekOfYear(n){const t=Go(n,!0);return function(n,t,e,o,r){const i=dr(n,o,r),s=Math.floor((Qo(wn,n,t,e)-i-1)/7)+1;if(s<1)return s+lr(n-1,o,r);const a=lr(n,o,r);return s>a?s-a:s}(t.isoYear,t.isoMonth,t.isoDay,1,4)}daysInWeek(n){return Go(n,!0),7}daysInMonth(n){const t=Wo(n,this,!0);return hr(this).daysInMonth(t.year,t.month)}daysInYear(n){const t=Wo(n,this,!0);return Jo(hr(this),t.year)}monthsInYear(n){const t=Wo(n,this,!0);return hr(this).monthsInYear(t.year)}inLeapYear(n){return hr(this).inLeapYear(this.year(n))}dateFromFields(n,t){const e=Ko(u(n,An),hr(this),t);return new Sr(e.isoYear,e.isoMonth,e.isoDay,this)}yearMonthFromFields(n,t){const e=Ko({...u(n,$n),day:1},hr(this),t);return new po(e.isoYear,e.isoMonth,this,e.isoDay)}monthDayFromFields(n,t){const e=hr(this);let{era:o,eraYear:r,year:i,month:s,monthCode:a,day:c}=u(n,Wn);if(void 0===c)throw new TypeError("required property 'day' missing or undefined");if(void 0!==a?i=pn:void 0!==o&&void 0!==r&&(i=mn(e.id,r,o)),void 0===i){if(void 0===a)throw new TypeError("either year or monthCode required with month");i=e.guessYearForMonthDay(a,c);}const d=Ko({year:i,month:s,monthCode:a,day:c},e,t);return new $o(d.isoMonth,d.isoDay,this,e.normalizeISOYearForMonthDay(d.isoYear))}dateAdd(n,e,o){const r=hr(this),i=function(n,e,o,r){n=pt(n=wt(n,e.years,o,r),e.months,o,r);let i=o.epochMilliseconds(n.year,n.month,n.day);const s=Math.trunc(cn(e).div(t).toNumber());return i=Un(i,7*e.weeks+e.days+s),Fn(i)}(N(Sr,n,o),N(ko,e),r,s$1(o));return new Sr(i.isoYear,i.isoMonth,i.isoDay,this)}dateUntil(n,t,e){const o=hr(this),r=N(Sr,n),i=N(Sr,t),s=d(e).largestUnit,a="auto"===s?6:F(s,6,6,9);return br(this,vr(r,i)),xo(function(n,t,e,o){let r=0,i=0,s=0,a=0;switch(o){case 9:r=function(n,t,e){const[,o,r]=qn(t.year,n.month,n.day,e,0),i=xn(t,n),s=P(t.month,o)||P(t.day,r);return t.year-n.year-(s&&i&&s!==i?i:0)}(n,t,e),n=wt(n,r,e,0);case 8:i=function(n,t,e){let o=0;const r=xn(t,n);if(r){let{year:i}=n;for(;i!==t.year;)o+=e.monthsInYear(i)*r,i+=r;const[,s,a]=qn(t.year,n.month,n.day,e,0);o+=t.month-s;const c=P(t.day,a);c&&r&&c!==r&&(o-=r);}return o}(n,t,e),n=pt(n,i,e,0);}a=Cn(e.epochMilliseconds(n.year,n.month,n.day),e.epochMilliseconds(t.year,t.month,t.day)),7===o&&(s=Math.trunc(a/7),a%=7);return nn({years:r,months:i,weeks:s,days:a,hours:0,minutes:0,seconds:0,milliseconds:0,microseconds:0,nanoseconds:0})}(r,i,o,a))}fields(n){return n.slice()}mergeFields(n,t){return yr(n,t)}toString(){return hr(this).id}}function gr(){return new mr("iso8601")}function yr(n,t){var e;const o={...n,...t};if(void 0!==n.year){delete o.era,delete o.eraYear,delete o.year;let e=!1;void 0===t.era&&void 0===t.eraYear||(o.era=t.era,o.eraYear=t.eraYear,e=!0),void 0!==t.year&&(o.year=t.year,e=!0),e||(o.year=n.year);}if(void 0!==n.monthCode){delete o.monthCode,delete o.month;let e=!1;void 0!==t.month&&(o.month=t.month,e=!0),void 0!==t.monthCode&&(o.monthCode=t.monthCode,e=!0),e||(o.monthCode=n.monthCode);}return void 0!==n.day&&(o.day=null!=(e=t.day)?e:n.day),o}function wr(n,t,e,o){const r=Sn(t,e,o);return ur(r,n.id),n.computeFields(r)}function pr(n){return void 0===n.calendar?gr():N(mr,n.calendar)}function vr(n,t){const{calendar:e}=n;return br(e,t.calendar),e}function Mr(n,t){const e=n.calendar,o=t.calendar;if("iso8601"===e.id)return o;if("iso8601"===o.id)return e;if(e.id!==o.id)throw new RangeError("Non-ISO calendars incompatible");return e}function br(n,t){if(n.toString()!==t.toString())throw new RangeError("Calendars must match")}mt(mr,"Calendar");class Sr extends U{constructor(n,t,e,o=gr()){const r=Hn({isoYear:n,isoMonth:t,isoDay:e},1),i=N(mr,o);!function(n,t){const e=Mn(n);Ge(e.add(e.sign()<0?86399999999999:0)),cr(e,t);}(r,i.toString()),super({...r,calendar:i});}static from(n,t){return s$1(t),n instanceof Sr?Ir(n.getISOFields()):"object"==typeof n?be(n,t):Ir(ne(xt(String(n))))}static compare(n,t){return Rn(N(Sr,n),N(Sr,t))}with(n,t){return De(this,n,t)}withCalendar(n){const t=this.getISOFields();return new Sr(t.isoYear,t.isoMonth,t.isoDay,n)}add(n,t){return this.calendar.dateAdd(this,n,t)}subtract(n,t){return this.calendar.dateAdd(this,N(ko,n).negated(),t)}until(n,t){return Fr(this,N(Sr,n),!1,t)}since(n,t){return Fr(this,N(Sr,n),!0,t)}equals(n){return !Rn(this,N(Sr,n))}toString(n){const t=Jn(n),e=this.getISOFields();return nt(e)+rt(e.calendar.toString(),t)}toZonedDateTime(n){const t=function(n){let t,e;if("string"==typeof n)e=n;else {if("object"!=typeof n)throw new TypeError("Invalid options/timeZone argument");if(void 0!==n.id?e=n:(e=n.timeZone,t=n.plainTime),void 0===e)throw new TypeError("Invalid timeZone argument")}return {plainTime:t,timeZone:e}}(n),e=N(we,t.timeZone),o=void 0===t.plainTime?void 0:N(ho,t.plainTime);return Fo({...this.getISOFields(),...o?o.getISOFields():on,timeZone:e})}toPlainDateTime(n){return Ho({...this.getISOFields(),...mo(n).getISOFields()})}toPlainYearMonth(){return vo(this.getISOFields())}toPlainMonthDay(){return this.calendar.monthDayFromFields(this)}}function Ir(n){return new Sr(n.isoYear,n.isoMonth,n.isoDay,n.calendar)}function Fr(n,t,e,o){return xo(Tr(n,t,vr(n,t),e,O(o,6,6,6,9)))}function Or(n,t,e,o,r){return Uo(Dr(n,t,e,r.largestUnit),n,t,e,o,r)}function Tr(n,t,e,o,r){return Uo(e.dateUntil(n,t,{largestUnit:M[r.largestUnit]}),n,t,e,o,r)}function Dr(n,t,e,o){if(!i(o))return Nr(n,t,o);const r=Ir({...n.getISOFields(),calendar:e});let s,a,c,u,d,l=Ir({...t.getISOFields(),calendar:e});do{a=e.dateUntil(r,l,{largestUnit:M[o]}),s=n.add(a),c=Nr(s,t,5),u=a.sign,d=c.sign;}while(u&&d&&u!==d&&(l=l.add({days:d})));return f=c,{sign:(h=a).sign||f.sign,years:h.years+f.years,months:h.months+f.months,weeks:h.weeks+f.weeks,days:h.days+f.days,hours:h.hours+f.hours,minutes:h.minutes+f.minutes,seconds:h.seconds+f.seconds,milliseconds:h.milliseconds+f.milliseconds,microseconds:h.microseconds+f.microseconds,nanoseconds:h.nanoseconds+f.nanoseconds};var h,f;}function Nr(n,t,e){return dn(On(t).sub(On(n)),e)}mt(Sr,"PlainDate"),dt(Sr),ft(Sr,ht),so(Sr,to({year:"numeric",month:"numeric",day:"numeric",weekday:void 0},{hour:void 0,minute:void 0,second:void 0}));class Yr extends E{constructor(n){super();const t=K(n,!0);!function(n){-1!==G(n,Ae)&&1!==G(n,$e)||Zn();}(t),this[vn]=t;}static from(n){if(n instanceof Yr)return new Yr(n.epochNanoseconds);const t=kt(String(n)),e=t.offsetNanoseconds;if(void 0===e)throw new RangeError("Must specify an offset");return new Yr(Mn(Ln(t,1)).sub(e))}static fromEpochSeconds(n){return new Yr(K(n).mult(1e9))}static fromEpochMilliseconds(n){return new Yr(K(n).mult(1e6))}static fromEpochMicroseconds(n){return new Yr(n*BigInt(1e3))}static fromEpochNanoseconds(n){return new Yr(n)}static compare(n,t){return jn(N(Yr,n),N(Yr,t))}add(n){return new Yr(Mt(this[vn],N(ko,n)))}subtract(n){return new Yr(Mt(this[vn],X(N(ko,n))))}until(n,t){return Er(this,N(Yr,n),t)}since(n,t){return Er(N(Yr,n),this,t)}round(n){const t=T(n,0,5,!0);return new Yr(Ve(this[vn],t))}equals(n){return !jn(this,N(Yr,n))}toString(n){const t=d(n).timeZone;return this.toZonedDateTimeISO(null!=t?t:"UTC").toString({...n,offset:void 0===t?"never":"auto",timeZoneName:"never"})+(void 0===t?"Z":"")}toZonedDateTimeISO(n){return new Io(this.epochNanoseconds,n)}toZonedDateTime(n){if(!h(n))throw new TypeError("Must specify options");if(void 0===n.calendar)throw new TypeError("Must specify a calendar");if(void 0===n.timeZone)throw new TypeError("Must specify a timeZone");return new Io(this.epochNanoseconds,n.timeZone,n.calendar)}}function Er(n,t,o){const r=O(o,3,0,0,5);return xo(function(n,t,o){return dn(q(t.sub(n),e[o.smallestUnit]*o.roundingIncrement,o.roundingFunc),o.largestUnit)}(n[vn],t[vn],r))}mt(Yr,"Instant"),at(Yr),so(Yr,_e({year:"numeric",month:"numeric",day:"numeric",weekday:void 0,hour:"numeric",minute:"2-digit",second:"2-digit"},{timeZoneName:void 0},{}));const Hr={zonedDateTimeISO:function(n){return Fo(Br("iso8601",n))},zonedDateTime:function(n,t){return Fo(Br(n,t))},plainDateTimeISO:function(n){return Ho(Br("iso8601",n))},plainDateTime:function(n,t){return Ho(Br(n,t))},plainDateISO:function(n){return Ir(Br("iso8601",n))},plainDate:function(n,t){return Ir(Br(n,t))},plainTimeISO:function(n){return fo(Br("iso8601",n))},instant:function(){return new Yr($r())},timeZone:Lr};mt(Hr,"Now");function Lr(){return new we((new ae).resolvedOptions().timeZone)}function Br(n,t=Lr()){const e=N(we,t);return {...Oo($r(),e)[0],timeZone:e,calendar:N(mr,n)}}function $r(){return K(Date.now()).mult(1e6)}const Ar={PlainYearMonth:po,PlainMonthDay:$o,PlainDate:Sr,PlainTime:ho,PlainDateTime:qo,ZonedDateTime:Io,Instant:Yr,Calendar:mr,TimeZone:we,Duration:ko,Now:Hr,[Symbol.toStringTag]:"Temporal"};
|
|
2141
2116
|
|
|
2142
|
-
|
|
2143
|
-
const epsilon = calcObliquityCorrection(t);
|
|
2144
|
-
const l0 = calcGeomMeanLongSun(t);
|
|
2145
|
-
const e = calcEccentricityEarthOrbit(t);
|
|
2146
|
-
const m = calcGeomMeanAnomalySun(t);
|
|
2117
|
+
const s=Ar;
|
|
2147
2118
|
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
const sin2m = Math.sin(2.0 * degToRad(m));
|
|
2156
|
-
|
|
2157
|
-
const Etime = y * sin2l0 - 2.0 * e * sinm + 4.0 * e * y * sinm * cos2l0 - 0.5 * y * y * sin4l0 - 1.25 * e * e * sin2m;
|
|
2158
|
-
return radToDeg(Etime) * 4.0; // in minutes of time
|
|
2119
|
+
/**
|
|
2120
|
+
* java.lang.Math.toRadians
|
|
2121
|
+
* @private
|
|
2122
|
+
* @param degrees
|
|
2123
|
+
*/
|
|
2124
|
+
function degreesToRadians(degrees) {
|
|
2125
|
+
return (degrees * Math.PI) / 180;
|
|
2159
2126
|
}
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2127
|
+
/**
|
|
2128
|
+
* java.lang.Math.toDegrees
|
|
2129
|
+
* @private
|
|
2130
|
+
* @param radians
|
|
2131
|
+
*/
|
|
2132
|
+
function radiansToDegrees(radians) {
|
|
2133
|
+
return (radians * 180) / Math.PI;
|
|
2167
2134
|
}
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2135
|
+
const Long_MIN_VALUE = NaN;
|
|
2136
|
+
/**
|
|
2137
|
+
* A class that contains location information such as latitude and longitude required for astronomical calculations. The
|
|
2138
|
+
* elevation field may not be used by some calculation engines and would be ignored if set. Check the documentation for
|
|
2139
|
+
* specific implementations of the {@link AstronomicalCalculator} to see if elevation is calculated as part of the
|
|
2140
|
+
* algorithm.
|
|
2141
|
+
*
|
|
2142
|
+
* @author © Eliyahu Hershfeld 2004 - 2016
|
|
2143
|
+
* @version 1.1
|
|
2144
|
+
*/
|
|
2145
|
+
class GeoLocation {
|
|
2146
|
+
/**
|
|
2147
|
+
* GeoLocation constructor with parameters for all required fields.
|
|
2148
|
+
*
|
|
2149
|
+
* @param {string} name
|
|
2150
|
+
* The location name for display use such as "Lakewood, NJ"
|
|
2151
|
+
* @param {number} latitude
|
|
2152
|
+
* the latitude in a double format such as 40.095965 for Lakewood, NJ.
|
|
2153
|
+
* <b>Note: </b> For latitudes south of the equator, a negative value should be used.
|
|
2154
|
+
* @param {number} longitude
|
|
2155
|
+
* double the longitude in a double format such as -74.222130 for Lakewood, NJ.
|
|
2156
|
+
* <b>Note: </b> For longitudes east of the <a href="http://en.wikipedia.org/wiki/Prime_Meridian">Prime
|
|
2157
|
+
* Meridian </a> (Greenwich), a negative value should be used.
|
|
2158
|
+
* @param {number} elevation
|
|
2159
|
+
* the elevation above sea level in Meters. Elevation is not used in most algorithms used for calculating
|
|
2160
|
+
* sunrise and set.
|
|
2161
|
+
* @param {string} timeZoneId
|
|
2162
|
+
* the <code>TimeZone</code> for the location.
|
|
2163
|
+
*/
|
|
2164
|
+
constructor(name, latitude, longitude, elevationOrTimeZoneId, timeZoneId) {
|
|
2165
|
+
/**
|
|
2166
|
+
* @private
|
|
2167
|
+
* @see #getLocationName()
|
|
2168
|
+
* @see #setLocationName(String)
|
|
2169
|
+
*/
|
|
2170
|
+
this.locationName = null;
|
|
2171
|
+
let elevation = 0;
|
|
2172
|
+
if (timeZoneId) {
|
|
2173
|
+
elevation = elevationOrTimeZoneId;
|
|
2174
|
+
}
|
|
2175
|
+
else {
|
|
2176
|
+
timeZoneId = elevationOrTimeZoneId;
|
|
2177
|
+
}
|
|
2178
|
+
this.setLocationName(name);
|
|
2179
|
+
this.setLatitude(latitude);
|
|
2180
|
+
this.setLongitude(longitude);
|
|
2181
|
+
this.setElevation(elevation);
|
|
2182
|
+
this.setTimeZone(timeZoneId);
|
|
2183
|
+
}
|
|
2184
|
+
/**
|
|
2185
|
+
* Method to get the elevation in Meters.
|
|
2186
|
+
*
|
|
2187
|
+
* @return {number} Returns the elevation in Meters.
|
|
2188
|
+
*/
|
|
2189
|
+
getElevation() {
|
|
2190
|
+
return this.elevation;
|
|
2191
|
+
}
|
|
2192
|
+
/**
|
|
2193
|
+
* Method to set the elevation in Meters <b>above </b> sea level.
|
|
2194
|
+
*
|
|
2195
|
+
* @param {number} elevation
|
|
2196
|
+
* The elevation to set in Meters. An IllegalArgumentException will be thrown if the value is a negative.
|
|
2197
|
+
*/
|
|
2198
|
+
setElevation(elevation) {
|
|
2199
|
+
this.elevation = elevation;
|
|
2200
|
+
}
|
|
2201
|
+
setLatitude(latitude) {
|
|
2202
|
+
if (typeof latitude !== 'number')
|
|
2203
|
+
throw new TypeError('Invalid latitude');
|
|
2204
|
+
if (latitude < -90 || latitude > 90) {
|
|
2205
|
+
throw new RangeError(`Latitude ${latitude} out of range [-90,90]`);
|
|
2206
|
+
}
|
|
2207
|
+
this.latitude = latitude;
|
|
2176
2208
|
}
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2209
|
+
/**
|
|
2210
|
+
* @return {number} Returns the latitude.
|
|
2211
|
+
*/
|
|
2212
|
+
getLatitude() {
|
|
2213
|
+
return this.latitude;
|
|
2214
|
+
}
|
|
2215
|
+
setLongitude(longitude) {
|
|
2216
|
+
if (typeof longitude !== 'number')
|
|
2217
|
+
throw new TypeError('Invalid longitude');
|
|
2218
|
+
if (longitude < -180 || longitude > 180) {
|
|
2219
|
+
throw new RangeError(`Longitude ${longitude} out of range [-180,180]`);
|
|
2220
|
+
}
|
|
2221
|
+
this.longitude = longitude;
|
|
2180
2222
|
}
|
|
2181
|
-
|
|
2182
|
-
|
|
2223
|
+
/**
|
|
2224
|
+
* @return {number} Returns the longitude.
|
|
2225
|
+
*/
|
|
2226
|
+
getLongitude() {
|
|
2227
|
+
return this.longitude;
|
|
2183
2228
|
}
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
return formatDate(date, solNoonLocal);
|
|
2217
|
-
// return timeString(solNoonLocal, 3);
|
|
2218
|
-
}
|
|
2219
|
-
|
|
2220
|
-
function calcSunriseSetUTC(rise, angle, JD, latitude, longitude) {
|
|
2221
|
-
const t = calcTimeJulianCent(JD);
|
|
2222
|
-
const eqTime = calcEquationOfTime(t);
|
|
2223
|
-
const solarDec = calcSunDeclination(t);
|
|
2224
|
-
let hourAngle = calcHourAngle(angle, latitude, solarDec);
|
|
2225
|
-
//alert("HA = " + radToDeg(hourAngle));
|
|
2226
|
-
if (!rise) hourAngle = -hourAngle;
|
|
2227
|
-
const delta = longitude + radToDeg(hourAngle);
|
|
2228
|
-
const timeUTC = 720 - (4.0 * delta) - eqTime; // in minutes
|
|
2229
|
-
return timeUTC;
|
|
2230
|
-
}
|
|
2231
|
-
|
|
2232
|
-
function calcSunriseSet(rise, angle, JD, date, latitude, longitude)
|
|
2233
|
-
// rise = 1 for sunrise, 0 for sunset
|
|
2234
|
-
{
|
|
2235
|
-
const timeUTC = calcSunriseSetUTC(rise, angle, JD, latitude, longitude);
|
|
2236
|
-
const newTimeUTC = calcSunriseSetUTC(rise, angle, JD + timeUTC / 1440.0, latitude, longitude);
|
|
2237
|
-
if (isNumber(newTimeUTC)) {
|
|
2238
|
-
|
|
2239
|
-
return formatDate(date, newTimeUTC);
|
|
2240
|
-
|
|
2241
|
-
} else { // no sunrise/set found
|
|
2242
|
-
return new Date(NaN);
|
|
2229
|
+
/**
|
|
2230
|
+
* @return {string|null} Returns the location name.
|
|
2231
|
+
*/
|
|
2232
|
+
getLocationName() {
|
|
2233
|
+
return this.locationName;
|
|
2234
|
+
}
|
|
2235
|
+
/**
|
|
2236
|
+
* @param {string|null} name
|
|
2237
|
+
* The setter method for the display name.
|
|
2238
|
+
*/
|
|
2239
|
+
setLocationName(name) {
|
|
2240
|
+
this.locationName = name;
|
|
2241
|
+
}
|
|
2242
|
+
/**
|
|
2243
|
+
* @return {string} Returns the timeZone.
|
|
2244
|
+
*/
|
|
2245
|
+
getTimeZone() {
|
|
2246
|
+
return this.timeZoneId;
|
|
2247
|
+
}
|
|
2248
|
+
/**
|
|
2249
|
+
* Method to set the TimeZone. If this is ever set after the GeoLocation is set in the
|
|
2250
|
+
* {@link AstronomicalCalendar}, it is critical that
|
|
2251
|
+
* {@link AstronomicalCalendar#getCalendar()}.
|
|
2252
|
+
* {@link java.util.Calendar#setTimeZone(TimeZone) setTimeZone(TimeZone)} be called in order for the
|
|
2253
|
+
* AstronomicalCalendar to output times in the expected offset. This situation will arise if the
|
|
2254
|
+
* AstronomicalCalendar is ever {@link AstronomicalCalendar#clone() cloned}.
|
|
2255
|
+
*
|
|
2256
|
+
* @param {string} timeZone
|
|
2257
|
+
* The timeZone to set.
|
|
2258
|
+
*/
|
|
2259
|
+
setTimeZone(timeZoneId) {
|
|
2260
|
+
this.timeZoneId = timeZoneId;
|
|
2243
2261
|
}
|
|
2244
|
-
}
|
|
2245
|
-
|
|
2246
|
-
const degreesBelowHorizon = {
|
|
2247
|
-
sunrise: 0.833,
|
|
2248
|
-
sunriseEnd: 0.3,
|
|
2249
|
-
twilight: 6,
|
|
2250
|
-
nauticalTwilight: 12,
|
|
2251
|
-
night: 18,
|
|
2252
|
-
goldenHour: -6
|
|
2253
|
-
};
|
|
2254
|
-
|
|
2255
|
-
class SolarCalc {
|
|
2256
|
-
constructor(date, latitude, longitude) {
|
|
2257
|
-
this.date = date;
|
|
2258
|
-
this.lat = latitude;
|
|
2259
|
-
this.longitude = longitude;
|
|
2260
|
-
|
|
2261
|
-
this.sun = new Sun(date, latitude, longitude);
|
|
2262
|
-
}
|
|
2263
|
-
|
|
2264
|
-
get solarNoon() {
|
|
2265
|
-
return this.sun.solarNoon;
|
|
2266
|
-
}
|
|
2267
|
-
|
|
2268
|
-
get sunrise() {
|
|
2269
|
-
return this.sun.timeAtAngle(degreesBelowHorizon.sunrise, true);
|
|
2270
|
-
}
|
|
2271
|
-
|
|
2272
|
-
get sunset() {
|
|
2273
|
-
return this.sun.timeAtAngle(degreesBelowHorizon.sunrise);
|
|
2274
|
-
}
|
|
2275
|
-
|
|
2276
|
-
get sunriseEnd() {
|
|
2277
|
-
return this.sun.timeAtAngle(degreesBelowHorizon.sunriseEnd, true);
|
|
2278
|
-
}
|
|
2279
|
-
|
|
2280
|
-
get sunsetStart() {
|
|
2281
|
-
return this.sun.timeAtAngle(degreesBelowHorizon.sunriseEnd, false);
|
|
2282
|
-
}
|
|
2283
|
-
|
|
2284
|
-
get civilDawn() {
|
|
2285
|
-
return this.sun.timeAtAngle(degreesBelowHorizon.twilight, true);
|
|
2286
|
-
}
|
|
2287
|
-
|
|
2288
|
-
get dawn() {
|
|
2289
|
-
return this.civilDawn;
|
|
2290
|
-
}
|
|
2291
|
-
|
|
2292
|
-
get civilDusk() {
|
|
2293
|
-
return this.sun.timeAtAngle(degreesBelowHorizon.twilight, false);
|
|
2294
|
-
}
|
|
2295
|
-
|
|
2296
|
-
get dusk() {
|
|
2297
|
-
return this.civilDusk;
|
|
2298
|
-
}
|
|
2299
|
-
|
|
2300
|
-
get nauticalDawn() {
|
|
2301
|
-
return this.sun.timeAtAngle(degreesBelowHorizon.nauticalTwilight, true);
|
|
2302
|
-
}
|
|
2303
|
-
|
|
2304
|
-
get nauticalDusk() {
|
|
2305
|
-
return this.sun.timeAtAngle(degreesBelowHorizon.nauticalTwilight, false);
|
|
2306
|
-
}
|
|
2307
|
-
|
|
2308
|
-
get nightStart() {
|
|
2309
|
-
return this.astronomicalDusk;
|
|
2310
|
-
}
|
|
2311
|
-
|
|
2312
|
-
get astronomicalDusk() {
|
|
2313
|
-
return this.sun.timeAtAngle(degreesBelowHorizon.night, false);
|
|
2314
|
-
}
|
|
2315
|
-
|
|
2316
|
-
get astronomicalDawn() {
|
|
2317
|
-
return this.sun.timeAtAngle(degreesBelowHorizon.night, true);
|
|
2318
|
-
}
|
|
2319
|
-
|
|
2320
|
-
get nightEnd() {
|
|
2321
|
-
return this.astronomicalDawn;
|
|
2322
|
-
}
|
|
2323
|
-
|
|
2324
|
-
get goldenHourStart() {
|
|
2325
|
-
return this.sun.timeAtAngle(degreesBelowHorizon.goldenHour, false);
|
|
2326
|
-
}
|
|
2327
|
-
|
|
2328
|
-
get goldenHourEnd() {
|
|
2329
|
-
return this.sun.timeAtAngle(degreesBelowHorizon.goldenHour, true);
|
|
2330
|
-
}
|
|
2331
2262
|
}
|
|
2332
|
-
|
|
2333
|
-
const _formatters = {};
|
|
2334
|
-
|
|
2335
2263
|
/**
|
|
2264
|
+
* The commonly used average solar refraction. Calendrical Calculations lists a more accurate global average of
|
|
2265
|
+
* 34.478885263888294
|
|
2336
2266
|
* @private
|
|
2337
|
-
* @param {string} tzid
|
|
2338
|
-
* @return {Intl.DateTimeFormat}
|
|
2339
2267
|
*/
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
if (fmt) return fmt;
|
|
2343
|
-
const f = new Intl.DateTimeFormat('en-US', {
|
|
2344
|
-
year: 'numeric',
|
|
2345
|
-
month: '2-digit',
|
|
2346
|
-
day: '2-digit',
|
|
2347
|
-
hour: '2-digit',
|
|
2348
|
-
minute: '2-digit',
|
|
2349
|
-
second: '2-digit',
|
|
2350
|
-
hour12: false,
|
|
2351
|
-
timeZone: tzid
|
|
2352
|
-
});
|
|
2353
|
-
_formatters[tzid] = f;
|
|
2354
|
-
return f;
|
|
2355
|
-
}
|
|
2356
|
-
const dateFormatRegex = /^(\d+).(\d+).(\d+),?\s+(\d+).(\d+).(\d+)/;
|
|
2357
|
-
|
|
2268
|
+
const refraction = 34 / 60;
|
|
2269
|
+
// private double refraction = 34.478885263888294 / 60d;
|
|
2358
2270
|
/**
|
|
2271
|
+
* The commonly used average solar radius in minutes of a degree.
|
|
2359
2272
|
* @private
|
|
2360
|
-
* @param {string} tzid
|
|
2361
|
-
* @param {Date} date
|
|
2362
|
-
* @return {string}
|
|
2363
2273
|
*/
|
|
2364
|
-
|
|
2365
|
-
const str = getFormatter$1(tzid).format(date);
|
|
2366
|
-
const m = dateFormatRegex.exec(str);
|
|
2367
|
-
let hour = m[4];
|
|
2368
|
-
if (hour == '24') hour = '00';
|
|
2369
|
-
m[3] = pad4(m[3]);
|
|
2370
|
-
return `${m[3]}-${m[1]}-${m[2]}T${hour}:${m[5]}:${m[6]}Z`;
|
|
2371
|
-
}
|
|
2372
|
-
|
|
2274
|
+
const solarRadius = 16 / 60;
|
|
2373
2275
|
/**
|
|
2276
|
+
* The commonly used average earth radius in KM. At this time, this only affects elevation adjustment and not the
|
|
2277
|
+
* sunrise and sunset calculations. The value currently defaults to 6356.9 KM.
|
|
2374
2278
|
* @private
|
|
2375
|
-
* @param {string} tzid
|
|
2376
|
-
* @param {Date} date
|
|
2377
|
-
* @return {number}
|
|
2378
2279
|
*/
|
|
2379
|
-
|
|
2380
|
-
const utcStr = getPseudoISO('UTC', date);
|
|
2381
|
-
const localStr = getPseudoISO(tzid, date);
|
|
2382
|
-
const diffMs = new Date(utcStr).getTime() - new Date(localStr).getTime();
|
|
2383
|
-
return Math.ceil(diffMs / 1000 / 60);
|
|
2384
|
-
}
|
|
2385
|
-
|
|
2280
|
+
const earthRadius = 6356.9; // in KM
|
|
2386
2281
|
/**
|
|
2387
|
-
*
|
|
2388
|
-
*
|
|
2389
|
-
*
|
|
2282
|
+
* Implementation of sunrise and sunset methods to calculate astronomical times based on the <a
|
|
2283
|
+
* href="http://noaa.gov">NOAA</a> algorithm. This calculator uses the Java algorithm based on the implementation by <a
|
|
2284
|
+
* href="http://noaa.gov">NOAA - National Oceanic and Atmospheric Administration</a>'s <a href =
|
|
2285
|
+
* "http://www.srrb.noaa.gov/highlights/sunrise/sunrise.html">Surface Radiation Research Branch</a>. NOAA's <a
|
|
2286
|
+
* href="http://www.srrb.noaa.gov/highlights/sunrise/solareqns.PDF">implementation</a> is based on equations from <a
|
|
2287
|
+
* href="http://www.willbell.com/math/mc1.htm">Astronomical Algorithms</a> by <a
|
|
2288
|
+
* href="http://en.wikipedia.org/wiki/Jean_Meeus">Jean Meeus</a>. Added to the algorithm is an adjustment of the zenith
|
|
2289
|
+
* to account for elevation. The algorithm can be found in the <a
|
|
2290
|
+
* href="http://en.wikipedia.org/wiki/Sunrise_equation">Wikipedia Sunrise Equation</a> article.
|
|
2291
|
+
*
|
|
2292
|
+
* @author © Eliyahu Hershfeld 2011 - 2019
|
|
2390
2293
|
*/
|
|
2391
|
-
|
|
2294
|
+
class NOAACalculator {
|
|
2295
|
+
/**
|
|
2296
|
+
* A constructor that takes in <a href="http://en.wikipedia.org/wiki/Geolocation">geolocation</a> information as a
|
|
2297
|
+
* parameter. The default {@link AstronomicalCalculator#getDefault() AstronomicalCalculator} used for solar
|
|
2298
|
+
* calculations is the the {@link NOAACalculator}.
|
|
2299
|
+
*
|
|
2300
|
+
* @param {GeoLocation} geoLocation
|
|
2301
|
+
* The location information used for calculating astronomical sun times.
|
|
2302
|
+
* @param {Temporal.PlainDate} date
|
|
2303
|
+
*
|
|
2304
|
+
* @see #setAstronomicalCalculator(AstronomicalCalculator) for changing the calculator class.
|
|
2305
|
+
*/
|
|
2306
|
+
constructor(geoLocation, date) {
|
|
2307
|
+
this.date = date;
|
|
2308
|
+
this.geoLocation = geoLocation;
|
|
2309
|
+
}
|
|
2310
|
+
/**
|
|
2311
|
+
* The getSunrise method Returns a `Date` representing the
|
|
2312
|
+
* {@link AstronomicalCalculator#getElevationAdjustment(double) elevation adjusted} sunrise time. The zenith used
|
|
2313
|
+
* for the calculation uses {@link #GEOMETRIC_ZENITH geometric zenith} of 90° plus
|
|
2314
|
+
* {@link AstronomicalCalculator#getElevationAdjustment(double)}. This is adjusted by the
|
|
2315
|
+
* {@link AstronomicalCalculator} to add approximately 50/60 of a degree to account for 34 archminutes of refraction
|
|
2316
|
+
* and 16 archminutes for the sun's radius for a total of {@link AstronomicalCalculator#adjustZenith 90.83333°}.
|
|
2317
|
+
* See documentation for the specific implementation of the {@link AstronomicalCalculator} that you are using.
|
|
2318
|
+
*
|
|
2319
|
+
* @return {Temporal.ZonedDateTime | null} the `Date` representing the exact sunrise time. If the calculation can't be computed such as
|
|
2320
|
+
* in the Arctic Circle where there is at least one day a year where the sun does not rise, and one where it
|
|
2321
|
+
* does not set, a null will be returned. See detailed explanation on top of the page.
|
|
2322
|
+
* @see AstronomicalCalculator#adjustZenith
|
|
2323
|
+
* @see #getSeaLevelSunrise()
|
|
2324
|
+
* @see AstronomicalCalendar#getUTCSunrise
|
|
2325
|
+
*/
|
|
2326
|
+
getSunrise() {
|
|
2327
|
+
const sunrise = this.getUTCSunrise0(NOAACalculator.GEOMETRIC_ZENITH);
|
|
2328
|
+
if (Number.isNaN(sunrise))
|
|
2329
|
+
return null;
|
|
2330
|
+
return this.getDateFromTime(sunrise, true);
|
|
2331
|
+
}
|
|
2332
|
+
/**
|
|
2333
|
+
* A method that returns the sunrise without {@link AstronomicalCalculator#getElevationAdjustment(double) elevation
|
|
2334
|
+
* adjustment}. Non-sunrise and sunset calculations such as dawn and dusk, depend on the amount of visible light,
|
|
2335
|
+
* something that is not affected by elevation. This method returns sunrise calculated at sea level. This forms the
|
|
2336
|
+
* base for dawn calculations that are calculated as a dip below the horizon before sunrise.
|
|
2337
|
+
*
|
|
2338
|
+
* @return {Temporal.ZonedDateTime | null} the `Date` representing the exact sea-level sunrise time. If the calculation can't be computed
|
|
2339
|
+
* such as in the Arctic Circle where there is at least one day a year where the sun does not rise, and one
|
|
2340
|
+
* where it does not set, a null will be returned. See detailed explanation on top of the page.
|
|
2341
|
+
* @see AstronomicalCalendar#getSunrise
|
|
2342
|
+
* @see AstronomicalCalendar#getUTCSeaLevelSunrise
|
|
2343
|
+
* @see #getSeaLevelSunset()
|
|
2344
|
+
*/
|
|
2345
|
+
getSeaLevelSunrise() {
|
|
2346
|
+
const sunrise = this.getUTCSeaLevelSunrise(NOAACalculator.GEOMETRIC_ZENITH);
|
|
2347
|
+
if (Number.isNaN(sunrise))
|
|
2348
|
+
return null;
|
|
2349
|
+
return this.getDateFromTime(sunrise, true);
|
|
2350
|
+
}
|
|
2351
|
+
/**
|
|
2352
|
+
* A method that returns the beginning of civil twilight (dawn) using a zenith of {@link #CIVIL_ZENITH 96°}.
|
|
2353
|
+
*
|
|
2354
|
+
* @return {Temporal.ZonedDateTime | null} The `Date` of the beginning of civil twilight using a zenith of 96°. If the calculation
|
|
2355
|
+
* can't be computed, null will be returned. See detailed explanation on top of the page.
|
|
2356
|
+
* @see #CIVIL_ZENITH
|
|
2357
|
+
*/
|
|
2358
|
+
getBeginCivilTwilight() {
|
|
2359
|
+
return this.getSunriseOffsetByDegrees(NOAACalculator.CIVIL_ZENITH);
|
|
2360
|
+
}
|
|
2361
|
+
/**
|
|
2362
|
+
* A method that returns the beginning of nautical twilight using a zenith of {@link #NAUTICAL_ZENITH 102°}.
|
|
2363
|
+
*
|
|
2364
|
+
* @return {Temporal.ZonedDateTime | null} The `Date` of the beginning of nautical twilight using a zenith of 102°. If the
|
|
2365
|
+
* calculation can't be computed null will be returned. See detailed explanation on top of the page.
|
|
2366
|
+
* @see #NAUTICAL_ZENITH
|
|
2367
|
+
*/
|
|
2368
|
+
getBeginNauticalTwilight() {
|
|
2369
|
+
return this.getSunriseOffsetByDegrees(NOAACalculator.NAUTICAL_ZENITH);
|
|
2370
|
+
}
|
|
2371
|
+
/**
|
|
2372
|
+
* A method that returns the beginning of astronomical twilight using a zenith of {@link #ASTRONOMICAL_ZENITH
|
|
2373
|
+
* 108°}.
|
|
2374
|
+
*
|
|
2375
|
+
* @return {Temporal.ZonedDateTime | null} The `Date` of the beginning of astronomical twilight using a zenith of 108°. If the
|
|
2376
|
+
* calculation can't be computed, null will be returned. See detailed explanation on top of the page.
|
|
2377
|
+
* @see #ASTRONOMICAL_ZENITH
|
|
2378
|
+
*/
|
|
2379
|
+
getBeginAstronomicalTwilight() {
|
|
2380
|
+
return this.getSunriseOffsetByDegrees(NOAACalculator.ASTRONOMICAL_ZENITH);
|
|
2381
|
+
}
|
|
2382
|
+
/**
|
|
2383
|
+
* The getSunset method Returns a `Date` representing the
|
|
2384
|
+
* {@link AstronomicalCalculator#getElevationAdjustment(double) elevation adjusted} sunset time. The zenith used for
|
|
2385
|
+
* the calculation uses {@link #GEOMETRIC_ZENITH geometric zenith} of 90° plus
|
|
2386
|
+
* {@link AstronomicalCalculator#getElevationAdjustment(double)}. This is adjusted by the
|
|
2387
|
+
* {@link AstronomicalCalculator} 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 AstronomicalCalculator#adjustZenith 90.83333°}.
|
|
2389
|
+
* See documentation for the specific implementation of the {@link AstronomicalCalculator} that you are using. Note:
|
|
2390
|
+
* In certain cases the calculates sunset will occur before sunrise. This will typically happen when a timezone
|
|
2391
|
+
* other than the local timezone is used (calculating Los Angeles sunset using a GMT timezone for example). In this
|
|
2392
|
+
* case the sunset date will be incremented to the following date.
|
|
2393
|
+
*
|
|
2394
|
+
* @return {Temporal.ZonedDateTime | null} The `Date` representing the exact sunset time. If the calculation can't be computed such as in
|
|
2395
|
+
* the Arctic Circle where there is at least one day a year where the sun does not rise, and one where it
|
|
2396
|
+
* does not set, a null will be returned. See detailed explanation on top of the page.
|
|
2397
|
+
* @see AstronomicalCalculator#adjustZenith
|
|
2398
|
+
* @see #getSeaLevelSunset()
|
|
2399
|
+
* @see AstronomicalCalendar#getUTCSunset
|
|
2400
|
+
*/
|
|
2401
|
+
getSunset() {
|
|
2402
|
+
const sunset = this.getUTCSunset0(NOAACalculator.GEOMETRIC_ZENITH);
|
|
2403
|
+
if (Number.isNaN(sunset))
|
|
2404
|
+
return null;
|
|
2405
|
+
return this.getDateFromTime(sunset, false);
|
|
2406
|
+
}
|
|
2407
|
+
/**
|
|
2408
|
+
* A method that returns the sunset without {@link AstronomicalCalculator#getElevationAdjustment(double) elevation
|
|
2409
|
+
* adjustment}. Non-sunrise and sunset calculations such as dawn and dusk, depend on the amount of visible light,
|
|
2410
|
+
* something that is not affected by elevation. This method returns sunset calculated at sea level. This forms the
|
|
2411
|
+
* base for dusk calculations that are calculated as a dip below the horizon after sunset.
|
|
2412
|
+
*
|
|
2413
|
+
* @return {Temporal.ZonedDateTime | null} The `Date` representing the exact sea-level sunset time. If the calculation can't be computed
|
|
2414
|
+
* such as in the Arctic Circle where there is at least one day a year where the sun does not rise, and one
|
|
2415
|
+
* where it does not set, a null will be returned. See detailed explanation on top of the page.
|
|
2416
|
+
* @see AstronomicalCalendar#getSunset
|
|
2417
|
+
* @see AstronomicalCalendar#getUTCSeaLevelSunset 2see {@link #getSunset()}
|
|
2418
|
+
*/
|
|
2419
|
+
getSeaLevelSunset() {
|
|
2420
|
+
const sunset = this.getUTCSeaLevelSunset(NOAACalculator.GEOMETRIC_ZENITH);
|
|
2421
|
+
if (Number.isNaN(sunset))
|
|
2422
|
+
return null;
|
|
2423
|
+
return this.getDateFromTime(sunset, false);
|
|
2424
|
+
}
|
|
2425
|
+
/**
|
|
2426
|
+
* A method that returns the end of civil twilight using a zenith of {@link #CIVIL_ZENITH 96°}.
|
|
2427
|
+
*
|
|
2428
|
+
* @return {Temporal.ZonedDateTime | null} The `Date` of the end of civil twilight using a zenith of {@link #CIVIL_ZENITH 96°}. If
|
|
2429
|
+
* the calculation can't be computed, null will be returned. See detailed explanation on top of the page.
|
|
2430
|
+
* @see #CIVIL_ZENITH
|
|
2431
|
+
*/
|
|
2432
|
+
getEndCivilTwilight() {
|
|
2433
|
+
return this.getSunsetOffsetByDegrees(NOAACalculator.CIVIL_ZENITH);
|
|
2434
|
+
}
|
|
2435
|
+
/**
|
|
2436
|
+
* A method that returns the end of nautical twilight using a zenith of {@link #NAUTICAL_ZENITH 102°}.
|
|
2437
|
+
*
|
|
2438
|
+
* @return {Temporal.ZonedDateTime | null} The `Date` of the end of nautical twilight using a zenith of {@link #NAUTICAL_ZENITH 102°}
|
|
2439
|
+
* . If the calculation can't be computed, null will be returned. See detailed explanation on top of the
|
|
2440
|
+
* page.
|
|
2441
|
+
* @see #NAUTICAL_ZENITH
|
|
2442
|
+
*/
|
|
2443
|
+
getEndNauticalTwilight() {
|
|
2444
|
+
return this.getSunsetOffsetByDegrees(NOAACalculator.NAUTICAL_ZENITH);
|
|
2445
|
+
}
|
|
2446
|
+
/**
|
|
2447
|
+
* A method that returns the end of astronomical twilight using a zenith of {@link #ASTRONOMICAL_ZENITH 108°}.
|
|
2448
|
+
*
|
|
2449
|
+
* @return {Temporal.ZonedDateTime | null} The `Date` of the end of astronomical twilight using a zenith of {@link #ASTRONOMICAL_ZENITH
|
|
2450
|
+
* 108°}. If the calculation can't be computed, null will be returned. See detailed explanation on top
|
|
2451
|
+
* of the page.
|
|
2452
|
+
* @see #ASTRONOMICAL_ZENITH
|
|
2453
|
+
*/
|
|
2454
|
+
getEndAstronomicalTwilight() {
|
|
2455
|
+
return this.getSunsetOffsetByDegrees(NOAACalculator.ASTRONOMICAL_ZENITH);
|
|
2456
|
+
}
|
|
2457
|
+
/**
|
|
2458
|
+
* A utility method that returns a date offset by the offset time passed in. Please note that the level of light
|
|
2459
|
+
* during twilight is not affected by elevation, so if this is being used to calculate an offset before sunrise or
|
|
2460
|
+
* after sunset with the intent of getting a rough "level of light" calculation, the sunrise or sunset time passed
|
|
2461
|
+
* to this method should be sea level sunrise and sunset.
|
|
2462
|
+
*
|
|
2463
|
+
* @param {Temporal.ZonedDateTime | null} time
|
|
2464
|
+
* the start time
|
|
2465
|
+
* @param {number} offset
|
|
2466
|
+
* the offset in milliseconds to add to the time.
|
|
2467
|
+
* @return {Temporal.ZonedDateTime | null} the `Date` with the offset in milliseconds added to it
|
|
2468
|
+
*/
|
|
2469
|
+
static getTimeOffset(time, offset) {
|
|
2470
|
+
if (time === null || offset === Long_MIN_VALUE || Number.isNaN(offset)) {
|
|
2471
|
+
return null;
|
|
2472
|
+
}
|
|
2473
|
+
return time.add({ milliseconds: offset });
|
|
2474
|
+
}
|
|
2475
|
+
/**
|
|
2476
|
+
* A utility method that returns the time of an offset by degrees below or above the horizon of
|
|
2477
|
+
* {@link #getSunrise() sunrise}. Note that the degree offset is from the vertical, so for a calculation of 14°
|
|
2478
|
+
* before sunrise, an offset of 14 + {@link #GEOMETRIC_ZENITH} = 104 would have to be passed as a parameter.
|
|
2479
|
+
*
|
|
2480
|
+
* @param {number} offsetZenith
|
|
2481
|
+
* the degrees before {@link #getSunrise()} to use in the calculation. For time after sunrise use
|
|
2482
|
+
* negative numbers. Note that the degree offset is from the vertical, so for a calculation of 14°
|
|
2483
|
+
* before sunrise, an offset of 14 + {@link #GEOMETRIC_ZENITH} = 104 would have to be passed as a
|
|
2484
|
+
* parameter.
|
|
2485
|
+
* @return {Temporal.ZonedDateTime | null} The `Date` of the offset after (or before) {@link #getSunrise()}. If the calculation
|
|
2486
|
+
* can't be computed such as in the Arctic Circle where there is at least one day a year where the sun does
|
|
2487
|
+
* not rise, and one where it does not set, a null will be returned. See detailed explanation on top of the
|
|
2488
|
+
* page.
|
|
2489
|
+
*/
|
|
2490
|
+
getSunriseOffsetByDegrees(offsetZenith) {
|
|
2491
|
+
const dawn = this.getUTCSunrise0(offsetZenith);
|
|
2492
|
+
if (Number.isNaN(dawn))
|
|
2493
|
+
return null;
|
|
2494
|
+
return this.getDateFromTime(dawn, true);
|
|
2495
|
+
}
|
|
2496
|
+
/**
|
|
2497
|
+
* A utility method that returns the time of an offset by degrees below or above the horizon of {@link #getSunset()
|
|
2498
|
+
* sunset}. Note that the degree offset is from the vertical, so for a calculation of 14° after sunset, an
|
|
2499
|
+
* offset of 14 + {@link #GEOMETRIC_ZENITH} = 104 would have to be passed as a parameter.
|
|
2500
|
+
*
|
|
2501
|
+
* @param {number} offsetZenith
|
|
2502
|
+
* the degrees after {@link #getSunset()} to use in the calculation. For time before sunset use negative
|
|
2503
|
+
* numbers. Note that the degree offset is from the vertical, so for a calculation of 14° after
|
|
2504
|
+
* sunset, an offset of 14 + {@link #GEOMETRIC_ZENITH} = 104 would have to be passed as a parameter.
|
|
2505
|
+
* @return {Temporal.ZonedDateTime | null} The `Date`of the offset after (or before) {@link #getSunset()}. If the calculation can't
|
|
2506
|
+
* be computed such as in the Arctic Circle where there is at least one day a year where the sun does not
|
|
2507
|
+
* rise, and one where it does not set, a null will be returned. See detailed explanation on top of the
|
|
2508
|
+
* page.
|
|
2509
|
+
*/
|
|
2510
|
+
getSunsetOffsetByDegrees(offsetZenith) {
|
|
2511
|
+
const sunset = this.getUTCSunset0(offsetZenith);
|
|
2512
|
+
if (Number.isNaN(sunset))
|
|
2513
|
+
return null;
|
|
2514
|
+
return this.getDateFromTime(sunset, false);
|
|
2515
|
+
}
|
|
2516
|
+
/**
|
|
2517
|
+
* A method that returns the sunrise in UTC time without correction for time zone offset from GMT and without using
|
|
2518
|
+
* daylight savings time.
|
|
2519
|
+
*
|
|
2520
|
+
* @param {number} zenith
|
|
2521
|
+
* the degrees below the horizon. For time after sunrise use negative numbers.
|
|
2522
|
+
* @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
|
|
2523
|
+
* Arctic Circle where there is at least one day a year where the sun does not rise, and one where it does
|
|
2524
|
+
* not set, {@link Double#NaN} will be returned. See detailed explanation on top of the page.
|
|
2525
|
+
*/
|
|
2526
|
+
getUTCSunrise0(zenith) {
|
|
2527
|
+
return this.getUTCSunrise(this.getAdjustedDate(), this.geoLocation, zenith, true);
|
|
2528
|
+
}
|
|
2529
|
+
/**
|
|
2530
|
+
* A method that returns the sunrise in UTC time without correction for time zone offset from GMT and without using
|
|
2531
|
+
* daylight savings time. Non-sunrise and sunset calculations such as dawn and dusk, depend on the amount of visible
|
|
2532
|
+
* light, something that is not affected by elevation. This method returns UTC sunrise calculated at sea level. This
|
|
2533
|
+
* forms the base for dawn calculations that are calculated as a dip below the horizon before sunrise.
|
|
2534
|
+
*
|
|
2535
|
+
* @param {number} zenith
|
|
2536
|
+
* the degrees below the horizon. For time after sunrise use negative numbers.
|
|
2537
|
+
* @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
|
|
2538
|
+
* Arctic Circle where there is at least one day a year where the sun does not rise, and one where it does
|
|
2539
|
+
* not set, {@link Double#NaN} will be returned. See detailed explanation on top of the page.
|
|
2540
|
+
* @see AstronomicalCalendar#getUTCSunrise
|
|
2541
|
+
* @see AstronomicalCalendar#getUTCSeaLevelSunset
|
|
2542
|
+
*/
|
|
2543
|
+
getUTCSeaLevelSunrise(zenith) {
|
|
2544
|
+
return this.getUTCSunrise(this.getAdjustedDate(), this.geoLocation, zenith, false);
|
|
2545
|
+
}
|
|
2546
|
+
/**
|
|
2547
|
+
* A method that returns the sunset in UTC time without correction for time zone offset from GMT and without using
|
|
2548
|
+
* daylight savings time.
|
|
2549
|
+
*
|
|
2550
|
+
* @param {number} zenith
|
|
2551
|
+
* the degrees below the horizon. For time after sunset use negative numbers.
|
|
2552
|
+
* @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
|
|
2553
|
+
* Arctic Circle where there is at least one day a year where the sun does not rise, and one where it does
|
|
2554
|
+
* not set, {@link Double#NaN} will be returned. See detailed explanation on top of the page.
|
|
2555
|
+
* @see AstronomicalCalendar#getUTCSeaLevelSunset
|
|
2556
|
+
*/
|
|
2557
|
+
getUTCSunset0(zenith) {
|
|
2558
|
+
return this.getUTCSunset(this.getAdjustedDate(), this.geoLocation, zenith, true);
|
|
2559
|
+
}
|
|
2560
|
+
/**
|
|
2561
|
+
* A method that returns the sunset in UTC time without correction for elevation, time zone offset from GMT and
|
|
2562
|
+
* without using daylight savings time. Non-sunrise and sunset calculations such as dawn and dusk, depend on the
|
|
2563
|
+
* amount of visible light, something that is not affected by elevation. This method returns UTC sunset calculated
|
|
2564
|
+
* at sea level. This forms the base for dusk calculations that are calculated as a dip below the horizon after
|
|
2565
|
+
* sunset.
|
|
2566
|
+
*
|
|
2567
|
+
* @param {number} zenith
|
|
2568
|
+
* the degrees below the horizon. For time before sunset use negative numbers.
|
|
2569
|
+
* @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
|
|
2570
|
+
* Arctic Circle where there is at least one day a year where the sun does not rise, and one where it does
|
|
2571
|
+
* not set, {@link Double#NaN} will be returned. See detailed explanation on top of the page.
|
|
2572
|
+
* @see AstronomicalCalendar#getUTCSunset
|
|
2573
|
+
* @see AstronomicalCalendar#getUTCSeaLevelSunrise
|
|
2574
|
+
*/
|
|
2575
|
+
getUTCSeaLevelSunset(zenith) {
|
|
2576
|
+
return this.getUTCSunset(this.getAdjustedDate(), this.geoLocation, zenith, false);
|
|
2577
|
+
}
|
|
2578
|
+
/**
|
|
2579
|
+
* Adjusts the <code>Calendar</code> to deal with edge cases where the location crosses the antimeridian.
|
|
2580
|
+
* @private
|
|
2581
|
+
* @see GeoLocation#getAntimeridianAdjustment()
|
|
2582
|
+
* @return the adjusted Calendar
|
|
2583
|
+
*/
|
|
2584
|
+
getAdjustedDate() {
|
|
2585
|
+
return this.date;
|
|
2586
|
+
}
|
|
2587
|
+
/**
|
|
2588
|
+
* Method to return the adjustment to the zenith required to account for the elevation. Since a person at a higher
|
|
2589
|
+
* elevation can see farther below the horizon, the calculation for sunrise / sunset is calculated below the horizon
|
|
2590
|
+
* used at sea level. This is only used for sunrise and sunset and not times before or after it such as
|
|
2591
|
+
* {@link AstronomicalCalendar#getBeginNauticalTwilight() nautical twilight} since those
|
|
2592
|
+
* calculations are based on the level of available light at the given dip below the horizon, something that is not
|
|
2593
|
+
* affected by elevation, the adjustment should only made if the zenith == 90° {@link #adjustZenith adjusted}
|
|
2594
|
+
* for refraction and solar radius. The algorithm used is
|
|
2595
|
+
*
|
|
2596
|
+
* <pre>
|
|
2597
|
+
* elevationAdjustment = Math.toDegrees(Math.acos(earthRadiusInMeters / (earthRadiusInMeters + elevationMeters)));
|
|
2598
|
+
* </pre>
|
|
2599
|
+
*
|
|
2600
|
+
* The source of this algorithm is <a href="http://www.calendarists.com">Calendrical Calculations</a> by Edward M.
|
|
2601
|
+
* Reingold and Nachum Dershowitz. An alternate algorithm that produces an almost identical (but not accurate)
|
|
2602
|
+
* result found in Ma'aglay Tzedek by Moishe Kosower and other sources is:
|
|
2603
|
+
*
|
|
2604
|
+
* <pre>
|
|
2605
|
+
* elevationAdjustment = 0.0347 * Math.sqrt(elevationMeters);
|
|
2606
|
+
* </pre>
|
|
2607
|
+
*
|
|
2608
|
+
* @param {number} elevation
|
|
2609
|
+
* elevation in Meters.
|
|
2610
|
+
* @return {number} the adjusted zenith
|
|
2611
|
+
*/
|
|
2612
|
+
getElevationAdjustment(elevation) {
|
|
2613
|
+
// double elevationAdjustment = 0.0347 * Math.sqrt(elevation);
|
|
2614
|
+
const elevationAdjustment = radiansToDegrees(Math.acos(earthRadius / (earthRadius + elevation / 1000)));
|
|
2615
|
+
return elevationAdjustment;
|
|
2616
|
+
}
|
|
2617
|
+
/**
|
|
2618
|
+
* Adjusts the zenith of astronomical sunrise and sunset to account for solar refraction, solar radius and
|
|
2619
|
+
* elevation. The value for Sun's zenith and true rise/set Zenith (used in this class and subclasses) is the angle
|
|
2620
|
+
* that the center of the Sun makes to a line perpendicular to the Earth's surface. If the Sun were a point and the
|
|
2621
|
+
* Earth were without an atmosphere, true sunset and sunrise would correspond to a 90° zenith. Because the Sun
|
|
2622
|
+
* is not a point, and because the atmosphere refracts light, this 90° zenith does not, in fact, correspond to
|
|
2623
|
+
* true sunset or sunrise, instead the centre of the Sun's disk must lie just below the horizon for the upper edge
|
|
2624
|
+
* to be obscured. This means that a zenith of just above 90° must be used. The Sun subtends an angle of 16
|
|
2625
|
+
* minutes of arc (this can be changed via the {@link #setSolarRadius(double)} method , and atmospheric refraction
|
|
2626
|
+
* accounts for 34 minutes or so (this can be changed via the {@link #setRefraction(double)} method), giving a total
|
|
2627
|
+
* of 50 arcminutes. The total value for ZENITH is 90+(5/6) or 90.8333333° for true sunrise/sunset. Since a
|
|
2628
|
+
* person at an elevation can see blow the horizon of a person at sea level, this will also adjust the zenith to
|
|
2629
|
+
* account for elevation if available. Note that this will only adjust the value if the zenith is exactly 90 degrees.
|
|
2630
|
+
* For values below and above this no correction is done. As an example, astronomical twilight is when the sun is
|
|
2631
|
+
* 18° below the horizon or {@link AstronomicalCalendar#ASTRONOMICAL_ZENITH 108°
|
|
2632
|
+
* below the zenith}. This is traditionally calculated with none of the above mentioned adjustments. The same goes
|
|
2633
|
+
* for various <em>tzais</em> and <em>alos</em> times such as the
|
|
2634
|
+
* {@link ZmanimCalendar#ZENITH_16_POINT_1 16.1°} dip used in
|
|
2635
|
+
* {@link ComplexZmanimCalendar#getAlos16Point1Degrees()}.
|
|
2636
|
+
*
|
|
2637
|
+
* @param {number} zenith
|
|
2638
|
+
* the azimuth below the vertical zenith of 90°. For sunset typically the {@link #adjustZenith
|
|
2639
|
+
* zenith} used for the calculation uses geometric zenith of 90° and {@link #adjustZenith adjusts}
|
|
2640
|
+
* this slightly to account for solar refraction and the sun's radius. Another example would be
|
|
2641
|
+
* {@link AstronomicalCalendar#getEndNauticalTwilight()} that passes
|
|
2642
|
+
* {@link AstronomicalCalendar#NAUTICAL_ZENITH} to this method.
|
|
2643
|
+
* @param {number} elevation
|
|
2644
|
+
* elevation in Meters.
|
|
2645
|
+
* @return {number} The zenith adjusted to include the {@link #getSolarRadius sun's radius}, {@link #getRefraction
|
|
2646
|
+
* refraction} and {@link #getElevationAdjustment elevation} adjustment. This will only be adjusted for
|
|
2647
|
+
* sunrise and sunset (if the zenith == 90°)
|
|
2648
|
+
* @see #getElevationAdjustment(double)
|
|
2649
|
+
*/
|
|
2650
|
+
adjustZenith(zenith, elevation) {
|
|
2651
|
+
let adjustedZenith = zenith;
|
|
2652
|
+
if (zenith === NOAACalculator.GEOMETRIC_ZENITH) {
|
|
2653
|
+
// only adjust if it is exactly sunrise or sunset
|
|
2654
|
+
adjustedZenith =
|
|
2655
|
+
zenith +
|
|
2656
|
+
(solarRadius + refraction + this.getElevationAdjustment(elevation));
|
|
2657
|
+
}
|
|
2658
|
+
return adjustedZenith;
|
|
2659
|
+
}
|
|
2660
|
+
/**
|
|
2661
|
+
* @see AstronomicalCalculator#getUTCSunrise(Calendar, GeoLocation, double, boolean)
|
|
2662
|
+
*/
|
|
2663
|
+
getUTCSunrise(date, geoLocation, zenith, adjustForElevation) {
|
|
2664
|
+
const elevation = adjustForElevation
|
|
2665
|
+
? geoLocation.getElevation()
|
|
2666
|
+
: 0;
|
|
2667
|
+
const adjustedZenith = this.adjustZenith(zenith, elevation);
|
|
2668
|
+
let sunrise = NOAACalculator.getSunriseUTC(NOAACalculator.getJulianDay(date), geoLocation.getLatitude(), -geoLocation.getLongitude(), adjustedZenith);
|
|
2669
|
+
sunrise = sunrise / 60;
|
|
2670
|
+
// ensure that the time is >= 0 and < 24
|
|
2671
|
+
while (sunrise < 0) {
|
|
2672
|
+
sunrise += 24;
|
|
2673
|
+
}
|
|
2674
|
+
while (sunrise >= 24) {
|
|
2675
|
+
sunrise -= 24;
|
|
2676
|
+
}
|
|
2677
|
+
return sunrise;
|
|
2678
|
+
}
|
|
2679
|
+
/**
|
|
2680
|
+
* @see AstronomicalCalculator#getUTCSunset(Calendar, GeoLocation, double, boolean)
|
|
2681
|
+
*/
|
|
2682
|
+
getUTCSunset(date, geoLocation, zenith, adjustForElevation) {
|
|
2683
|
+
const elevation = adjustForElevation
|
|
2684
|
+
? geoLocation.getElevation()
|
|
2685
|
+
: 0;
|
|
2686
|
+
const adjustedZenith = this.adjustZenith(zenith, elevation);
|
|
2687
|
+
let sunset = NOAACalculator.getSunsetUTC(NOAACalculator.getJulianDay(date), geoLocation.getLatitude(), -geoLocation.getLongitude(), adjustedZenith);
|
|
2688
|
+
sunset = sunset / 60;
|
|
2689
|
+
// ensure that the time is >= 0 and < 24
|
|
2690
|
+
while (sunset < 0) {
|
|
2691
|
+
sunset += 24;
|
|
2692
|
+
}
|
|
2693
|
+
while (sunset >= 24) {
|
|
2694
|
+
sunset -= 24;
|
|
2695
|
+
}
|
|
2696
|
+
return sunset;
|
|
2697
|
+
}
|
|
2698
|
+
/**
|
|
2699
|
+
* A utility method that will allow the calculation of a temporal (solar) hour based on the sunrise and sunset
|
|
2700
|
+
* passed as parameters to this method. An example of the use of this method would be the calculation of a
|
|
2701
|
+
* non-elevation adjusted temporal hour by passing in {@link #getSeaLevelSunrise() sea level sunrise} and
|
|
2702
|
+
* {@link #getSeaLevelSunset() sea level sunset} as parameters.
|
|
2703
|
+
*
|
|
2704
|
+
* @param {Temporal.ZonedDateTime | null} startOfDay
|
|
2705
|
+
* The start of the day.
|
|
2706
|
+
* @param {Temporal.ZonedDateTime | null} endOfDay
|
|
2707
|
+
* The end of the day.
|
|
2708
|
+
*
|
|
2709
|
+
* @return {number} the <code>long</code> millisecond length of the temporal hour. If the calculation can't be computed a
|
|
2710
|
+
* {@link Long#MIN_VALUE} will be returned. See detailed explanation on top of the page.
|
|
2711
|
+
*
|
|
2712
|
+
* @see #getTemporalHour()
|
|
2713
|
+
*/
|
|
2714
|
+
getTemporalHour(startOfDay = this.getSeaLevelSunrise(), endOfDay = this.getSeaLevelSunset()) {
|
|
2715
|
+
if (startOfDay === null || endOfDay === null) {
|
|
2716
|
+
return Long_MIN_VALUE;
|
|
2717
|
+
}
|
|
2718
|
+
const delta = endOfDay.epochMilliseconds - startOfDay.epochMilliseconds;
|
|
2719
|
+
return Math.floor(delta / 12);
|
|
2720
|
+
}
|
|
2721
|
+
/**
|
|
2722
|
+
* A method that returns sundial or solar noon. It occurs when the Sun is <a href
|
|
2723
|
+
* ="http://en.wikipedia.org/wiki/Transit_%28astronomy%29">transiting</a> the <a
|
|
2724
|
+
* href="http://en.wikipedia.org/wiki/Meridian_%28astronomy%29">celestial meridian</a>. In this class it is
|
|
2725
|
+
* calculated as halfway between the sunrise and sunset passed to this method. This time can be slightly off the
|
|
2726
|
+
* real transit time due to changes in declination (the lengthening or shortening day).
|
|
2727
|
+
*
|
|
2728
|
+
* @param {Temporal.ZonedDateTime | null} startOfDay
|
|
2729
|
+
* the start of day for calculating the sun's transit. This can be sea level sunrise, visual sunrise (or
|
|
2730
|
+
* any arbitrary start of day) passed to this method.
|
|
2731
|
+
* @param {Temporal.ZonedDateTime | null} endOfDay
|
|
2732
|
+
* the end of day for calculating the sun's transit. This can be sea level sunset, visual sunset (or any
|
|
2733
|
+
* arbitrary end of day) passed to this method.
|
|
2734
|
+
*
|
|
2735
|
+
* @return {Temporal.ZonedDateTime | null} The `Date` representing Sun's transit. If the calculation can't be computed such as in the
|
|
2736
|
+
* Arctic Circle where there is at least one day a year where the sun does not rise, and one where it does
|
|
2737
|
+
* not set, null will be returned. See detailed explanation on top of the page.
|
|
2738
|
+
*/
|
|
2739
|
+
getSunTransit(startOfDay = this.getSeaLevelSunrise(), endOfDay = this.getSeaLevelSunset()) {
|
|
2740
|
+
const temporalHour = this.getTemporalHour(startOfDay, endOfDay);
|
|
2741
|
+
return NOAACalculator.getTimeOffset(startOfDay, temporalHour * 6);
|
|
2742
|
+
}
|
|
2743
|
+
/**
|
|
2744
|
+
* A method that returns a `Date` from the time passed in as a parameter.
|
|
2745
|
+
* @protected
|
|
2746
|
+
* @param {number} time
|
|
2747
|
+
* The time to be set as the time for the `Date`. The time expected is in the format: 18.75
|
|
2748
|
+
* for 6:45:00 PM.
|
|
2749
|
+
* @param {boolean} isSunrise true if the time is sunrise, and false if it is sunset
|
|
2750
|
+
* @return {Temporal.ZonedDateTime | null} The Date.
|
|
2751
|
+
*/
|
|
2752
|
+
getDateFromTime(time, isSunrise) {
|
|
2753
|
+
if (Number.isNaN(time)) {
|
|
2754
|
+
return null;
|
|
2755
|
+
}
|
|
2756
|
+
let calculatedTime = time;
|
|
2757
|
+
let cal = this.getAdjustedDate();
|
|
2758
|
+
// let cal = new Temporal.PlainDate(adj.year, adj.month, adj.day);
|
|
2759
|
+
const hours = Math.trunc(calculatedTime); // retain only the hours
|
|
2760
|
+
calculatedTime -= hours;
|
|
2761
|
+
const minutes = Math.trunc((calculatedTime *= 60)); // retain only the minutes
|
|
2762
|
+
calculatedTime -= minutes;
|
|
2763
|
+
const seconds = Math.trunc((calculatedTime *= 60)); // retain only the seconds
|
|
2764
|
+
calculatedTime -= seconds; // remaining milliseconds
|
|
2765
|
+
// Check if a date transition has occurred, or is about to occur - this indicates the date of the event is
|
|
2766
|
+
// actually not the target date, but the day prior or after
|
|
2767
|
+
const localTimeHours = Math.trunc(this.geoLocation.getLongitude() / 15);
|
|
2768
|
+
if (isSunrise && localTimeHours + hours > 18) {
|
|
2769
|
+
cal = cal.add({ days: -1 });
|
|
2770
|
+
// cal = cal.minus({days: 1});
|
|
2771
|
+
}
|
|
2772
|
+
else if (!isSunrise && localTimeHours + hours < 6) {
|
|
2773
|
+
cal = cal.add({ days: 1 });
|
|
2774
|
+
}
|
|
2775
|
+
return cal
|
|
2776
|
+
.toZonedDateTime({
|
|
2777
|
+
timeZone: 'UTC',
|
|
2778
|
+
plainTime: new s.PlainTime(hours, minutes, seconds, Math.trunc(calculatedTime * 1000)),
|
|
2779
|
+
})
|
|
2780
|
+
.withTimeZone(this.geoLocation.getTimeZone());
|
|
2781
|
+
}
|
|
2782
|
+
/**
|
|
2783
|
+
* Return the <a href="http://en.wikipedia.org/wiki/Julian_day">Julian day</a> from a Java Calendar
|
|
2784
|
+
* @private
|
|
2785
|
+
* @param {Temporal.ZonedDateTime} date
|
|
2786
|
+
* The Java Calendar
|
|
2787
|
+
* @return the Julian day corresponding to the date Note: Number is returned for start of day. Fractional days
|
|
2788
|
+
* should be added later.
|
|
2789
|
+
*/
|
|
2790
|
+
static getJulianDay(date) {
|
|
2791
|
+
let { year, month } = date;
|
|
2792
|
+
const { day } = date;
|
|
2793
|
+
if (month <= 2) {
|
|
2794
|
+
year -= 1;
|
|
2795
|
+
month += 12;
|
|
2796
|
+
}
|
|
2797
|
+
const a = Math.trunc(year / 100);
|
|
2798
|
+
const b = Math.trunc(2 - a + a / 4);
|
|
2799
|
+
return (Math.floor(365.25 * (year + 4716)) +
|
|
2800
|
+
Math.floor(30.6001 * (month + 1)) +
|
|
2801
|
+
day +
|
|
2802
|
+
b -
|
|
2803
|
+
1524.5);
|
|
2804
|
+
}
|
|
2805
|
+
/**
|
|
2806
|
+
* Convert <a href="http://en.wikipedia.org/wiki/Julian_day">Julian day</a> to centuries since J2000.0.
|
|
2807
|
+
* @private
|
|
2808
|
+
* @param julianDay
|
|
2809
|
+
* the Julian Day to convert
|
|
2810
|
+
* @return the centuries since 2000 Julian corresponding to the Julian Day
|
|
2811
|
+
*/
|
|
2812
|
+
static getJulianCenturiesFromJulianDay(julianDay) {
|
|
2813
|
+
return ((julianDay - NOAACalculator.JULIAN_DAY_JAN_1_2000) /
|
|
2814
|
+
NOAACalculator.JULIAN_DAYS_PER_CENTURY);
|
|
2815
|
+
}
|
|
2816
|
+
/**
|
|
2817
|
+
* Convert centuries since J2000.0 to <a href="http://en.wikipedia.org/wiki/Julian_day">Julian day</a>.
|
|
2818
|
+
* @private
|
|
2819
|
+
* @param julianCenturies
|
|
2820
|
+
* the number of Julian centuries since J2000.0
|
|
2821
|
+
* @return the Julian Day corresponding to the Julian centuries passed in
|
|
2822
|
+
*/
|
|
2823
|
+
static getJulianDayFromJulianCenturies(julianCenturies) {
|
|
2824
|
+
return (julianCenturies * NOAACalculator.JULIAN_DAYS_PER_CENTURY +
|
|
2825
|
+
NOAACalculator.JULIAN_DAY_JAN_1_2000);
|
|
2826
|
+
}
|
|
2827
|
+
/**
|
|
2828
|
+
* Returns the Geometric <a href="http://en.wikipedia.org/wiki/Mean_longitude">Mean Longitude</a> of the Sun.
|
|
2829
|
+
* @private
|
|
2830
|
+
* @param julianCenturies
|
|
2831
|
+
* the number of Julian centuries since J2000.0
|
|
2832
|
+
* @return the Geometric Mean Longitude of the Sun in degrees
|
|
2833
|
+
*/
|
|
2834
|
+
static getSunGeometricMeanLongitude(julianCenturies) {
|
|
2835
|
+
let longitude = 280.46646 + julianCenturies * (36000.76983 + 0.0003032 * julianCenturies);
|
|
2836
|
+
while (longitude > 360) {
|
|
2837
|
+
longitude -= 360;
|
|
2838
|
+
}
|
|
2839
|
+
while (longitude < 0) {
|
|
2840
|
+
longitude += 360;
|
|
2841
|
+
}
|
|
2842
|
+
return longitude; // in degrees
|
|
2843
|
+
}
|
|
2844
|
+
/**
|
|
2845
|
+
* Returns the Geometric <a href="http://en.wikipedia.org/wiki/Mean_anomaly">Mean Anomaly</a> of the Sun.
|
|
2846
|
+
* @private
|
|
2847
|
+
* @param julianCenturies
|
|
2848
|
+
* the number of Julian centuries since J2000.0
|
|
2849
|
+
* @return the Geometric Mean Anomaly of the Sun in degrees
|
|
2850
|
+
*/
|
|
2851
|
+
static getSunGeometricMeanAnomaly(julianCenturies) {
|
|
2852
|
+
return (357.52911 + julianCenturies * (35999.05029 - 0.0001537 * julianCenturies)); // in degrees
|
|
2853
|
+
}
|
|
2854
|
+
/**
|
|
2855
|
+
* Return the <a href="http://en.wikipedia.org/wiki/Eccentricity_%28orbit%29">eccentricity of earth's orbit</a>.
|
|
2856
|
+
* @private
|
|
2857
|
+
* @param julianCenturies
|
|
2858
|
+
* the number of Julian centuries since J2000.0
|
|
2859
|
+
* @return the unitless eccentricity
|
|
2860
|
+
*/
|
|
2861
|
+
static getEarthOrbitEccentricity(julianCenturies) {
|
|
2862
|
+
return (0.016708634 -
|
|
2863
|
+
julianCenturies * (0.000042037 + 0.0000001267 * julianCenturies)); // unitless
|
|
2864
|
+
}
|
|
2865
|
+
/**
|
|
2866
|
+
* Returns the <a href="http://en.wikipedia.org/wiki/Equation_of_the_center">equation of center</a> for the sun.
|
|
2867
|
+
* @private
|
|
2868
|
+
* @param julianCenturies
|
|
2869
|
+
* the number of Julian centuries since J2000.0
|
|
2870
|
+
* @return the equation of center for the sun in degrees
|
|
2871
|
+
*/
|
|
2872
|
+
static getSunEquationOfCenter(julianCenturies) {
|
|
2873
|
+
const m = NOAACalculator.getSunGeometricMeanAnomaly(julianCenturies);
|
|
2874
|
+
const mrad = degreesToRadians(m);
|
|
2875
|
+
const sinm = Math.sin(mrad);
|
|
2876
|
+
const sin2m = Math.sin(mrad + mrad);
|
|
2877
|
+
const sin3m = Math.sin(mrad + mrad + mrad);
|
|
2878
|
+
return (sinm *
|
|
2879
|
+
(1.914602 - julianCenturies * (0.004817 + 0.000014 * julianCenturies)) +
|
|
2880
|
+
sin2m * (0.019993 - 0.000101 * julianCenturies) +
|
|
2881
|
+
sin3m * 0.000289); // in degrees
|
|
2882
|
+
}
|
|
2883
|
+
/**
|
|
2884
|
+
* Return the true longitude of the sun
|
|
2885
|
+
* @private
|
|
2886
|
+
* @param julianCenturies
|
|
2887
|
+
* the number of Julian centuries since J2000.0
|
|
2888
|
+
* @return the sun's true longitude in degrees
|
|
2889
|
+
*/
|
|
2890
|
+
static getSunTrueLongitude(julianCenturies) {
|
|
2891
|
+
const sunLongitude = NOAACalculator.getSunGeometricMeanLongitude(julianCenturies);
|
|
2892
|
+
const center = NOAACalculator.getSunEquationOfCenter(julianCenturies);
|
|
2893
|
+
return sunLongitude + center; // in degrees
|
|
2894
|
+
}
|
|
2895
|
+
/**
|
|
2896
|
+
* Return the apparent longitude of the sun
|
|
2897
|
+
* @private
|
|
2898
|
+
* @param julianCenturies
|
|
2899
|
+
* the number of Julian centuries since J2000.0
|
|
2900
|
+
* @return sun's apparent longitude in degrees
|
|
2901
|
+
*/
|
|
2902
|
+
static getSunApparentLongitude(julianCenturies) {
|
|
2903
|
+
const sunTrueLongitude = NOAACalculator.getSunTrueLongitude(julianCenturies);
|
|
2904
|
+
const omega = 125.04 - 1934.136 * julianCenturies;
|
|
2905
|
+
const lambda = sunTrueLongitude - 0.00569 - 0.00478 * Math.sin(degreesToRadians(omega));
|
|
2906
|
+
return lambda; // in degrees
|
|
2907
|
+
}
|
|
2908
|
+
/**
|
|
2909
|
+
* Returns the mean <a href="http://en.wikipedia.org/wiki/Axial_tilt">obliquity of the ecliptic</a> (Axial tilt).
|
|
2910
|
+
* @private
|
|
2911
|
+
* @param julianCenturies
|
|
2912
|
+
* the number of Julian centuries since J2000.0
|
|
2913
|
+
* @return the mean obliquity in degrees
|
|
2914
|
+
*/
|
|
2915
|
+
static getMeanObliquityOfEcliptic(julianCenturies) {
|
|
2916
|
+
const seconds = 21.448 -
|
|
2917
|
+
julianCenturies *
|
|
2918
|
+
(46.815 + julianCenturies * (0.00059 - julianCenturies * 0.001813));
|
|
2919
|
+
return 23 + (26 + seconds / 60) / 60; // in degrees
|
|
2920
|
+
}
|
|
2921
|
+
/**
|
|
2922
|
+
* Returns the corrected <a href="http://en.wikipedia.org/wiki/Axial_tilt">obliquity of the ecliptic</a> (Axial
|
|
2923
|
+
* tilt).
|
|
2924
|
+
* @private
|
|
2925
|
+
* @param julianCenturies
|
|
2926
|
+
* the number of Julian centuries since J2000.0
|
|
2927
|
+
* @return the corrected obliquity in degrees
|
|
2928
|
+
*/
|
|
2929
|
+
static getObliquityCorrection(julianCenturies) {
|
|
2930
|
+
const obliquityOfEcliptic = NOAACalculator.getMeanObliquityOfEcliptic(julianCenturies);
|
|
2931
|
+
const omega = 125.04 - 1934.136 * julianCenturies;
|
|
2932
|
+
return obliquityOfEcliptic + 0.00256 * Math.cos(degreesToRadians(omega)); // in degrees
|
|
2933
|
+
}
|
|
2934
|
+
/**
|
|
2935
|
+
* Return the <a href="http://en.wikipedia.org/wiki/Declination">declination</a> of the sun.
|
|
2936
|
+
* @private
|
|
2937
|
+
* @param julianCenturies
|
|
2938
|
+
* the number of Julian centuries since J2000.0
|
|
2939
|
+
* @return
|
|
2940
|
+
* the sun's declination in degrees
|
|
2941
|
+
*/
|
|
2942
|
+
static getSunDeclination(julianCenturies) {
|
|
2943
|
+
const obliquityCorrection = NOAACalculator.getObliquityCorrection(julianCenturies);
|
|
2944
|
+
const lambda = NOAACalculator.getSunApparentLongitude(julianCenturies);
|
|
2945
|
+
const sint = Math.sin(degreesToRadians(obliquityCorrection)) *
|
|
2946
|
+
Math.sin(degreesToRadians(lambda));
|
|
2947
|
+
const theta = radiansToDegrees(Math.asin(sint));
|
|
2948
|
+
return theta; // in degrees
|
|
2949
|
+
}
|
|
2950
|
+
/**
|
|
2951
|
+
* Return the <a href="http://en.wikipedia.org/wiki/Equation_of_time">Equation of Time</a> - the difference between
|
|
2952
|
+
* true solar time and mean solar time
|
|
2953
|
+
* @private
|
|
2954
|
+
* @param julianCenturies
|
|
2955
|
+
* the number of Julian centuries since J2000.0
|
|
2956
|
+
* @return equation of time in minutes of time
|
|
2957
|
+
*/
|
|
2958
|
+
static getEquationOfTime(julianCenturies) {
|
|
2959
|
+
const epsilon = NOAACalculator.getObliquityCorrection(julianCenturies);
|
|
2960
|
+
const geomMeanLongSun = NOAACalculator.getSunGeometricMeanLongitude(julianCenturies);
|
|
2961
|
+
const eccentricityEarthOrbit = NOAACalculator.getEarthOrbitEccentricity(julianCenturies);
|
|
2962
|
+
const geomMeanAnomalySun = NOAACalculator.getSunGeometricMeanAnomaly(julianCenturies);
|
|
2963
|
+
let y = Math.tan(degreesToRadians(epsilon) / 2);
|
|
2964
|
+
y *= y;
|
|
2965
|
+
const sin2l0 = Math.sin(2 * degreesToRadians(geomMeanLongSun));
|
|
2966
|
+
const sinm = Math.sin(degreesToRadians(geomMeanAnomalySun));
|
|
2967
|
+
const cos2l0 = Math.cos(2 * degreesToRadians(geomMeanLongSun));
|
|
2968
|
+
const sin4l0 = Math.sin(4 * degreesToRadians(geomMeanLongSun));
|
|
2969
|
+
const sin2m = Math.sin(2 * degreesToRadians(geomMeanAnomalySun));
|
|
2970
|
+
const equationOfTime = y * sin2l0 -
|
|
2971
|
+
2 * eccentricityEarthOrbit * sinm +
|
|
2972
|
+
4 * eccentricityEarthOrbit * y * sinm * cos2l0 -
|
|
2973
|
+
0.5 * y * y * sin4l0 -
|
|
2974
|
+
1.25 * eccentricityEarthOrbit * eccentricityEarthOrbit * sin2m;
|
|
2975
|
+
return radiansToDegrees(equationOfTime) * 4; // in minutes of time
|
|
2976
|
+
}
|
|
2977
|
+
/**
|
|
2978
|
+
* Return the <a href="http://en.wikipedia.org/wiki/Hour_angle">hour angle</a> of the sun at sunrise for the
|
|
2979
|
+
* latitude.
|
|
2980
|
+
* @private
|
|
2981
|
+
* @param {number} lat
|
|
2982
|
+
* , the latitude of observer in degrees
|
|
2983
|
+
* @param solarDec
|
|
2984
|
+
* the declination angle of sun in degrees
|
|
2985
|
+
* @param {number} zenith
|
|
2986
|
+
* the zenith
|
|
2987
|
+
* @return hour angle of sunrise in radians
|
|
2988
|
+
*/
|
|
2989
|
+
static getSunHourAngleAtSunrise(lat, solarDec, zenith) {
|
|
2990
|
+
const latRad = degreesToRadians(lat);
|
|
2991
|
+
const sdRad = degreesToRadians(solarDec);
|
|
2992
|
+
return Math.acos(Math.cos(degreesToRadians(zenith)) /
|
|
2993
|
+
(Math.cos(latRad) * Math.cos(sdRad)) -
|
|
2994
|
+
Math.tan(latRad) * Math.tan(sdRad)); // in radians
|
|
2995
|
+
}
|
|
2996
|
+
/**
|
|
2997
|
+
* Returns the <a href="http://en.wikipedia.org/wiki/Hour_angle">hour angle</a> of the sun at sunset for the
|
|
2998
|
+
* latitude. TODO: use - {@link #getSunHourAngleAtSunrise(double, double, double)} implementation to avoid
|
|
2999
|
+
* duplication of code.
|
|
3000
|
+
* @private
|
|
3001
|
+
* @param {number} lat
|
|
3002
|
+
* the latitude of observer in degrees
|
|
3003
|
+
* @param solarDec
|
|
3004
|
+
* the declination angle of sun in degrees
|
|
3005
|
+
* @param {number} zenith
|
|
3006
|
+
* the zenith
|
|
3007
|
+
* @return the hour angle of sunset in radians
|
|
3008
|
+
*/
|
|
3009
|
+
static getSunHourAngleAtSunset(lat, solarDec, zenith) {
|
|
3010
|
+
const latRad = degreesToRadians(lat);
|
|
3011
|
+
const sdRad = degreesToRadians(solarDec);
|
|
3012
|
+
const hourAngle = Math.acos(Math.cos(degreesToRadians(zenith)) /
|
|
3013
|
+
(Math.cos(latRad) * Math.cos(sdRad)) -
|
|
3014
|
+
Math.tan(latRad) * Math.tan(sdRad));
|
|
3015
|
+
return -hourAngle; // in radians
|
|
3016
|
+
}
|
|
3017
|
+
/**
|
|
3018
|
+
* Return the <a href="http://en.wikipedia.org/wiki/Celestial_coordinate_system">Solar Elevation</a> for the
|
|
3019
|
+
* horizontal coordinate system at the given location at the given time. Can be negative if the sun is below the
|
|
3020
|
+
* horizon. Not corrected for altitude.
|
|
3021
|
+
*
|
|
3022
|
+
* @param {Temporal.ZonedDateTime} date
|
|
3023
|
+
* time of calculation
|
|
3024
|
+
* @param {number} lat
|
|
3025
|
+
* latitude of location for calculation
|
|
3026
|
+
* @param {number} lon
|
|
3027
|
+
* longitude of location for calculation
|
|
3028
|
+
* @return {number} solar elevation in degrees - horizon is 0 degrees, civil twilight is -6 degrees
|
|
3029
|
+
*/
|
|
3030
|
+
static getSolarElevation(date, lat, lon) {
|
|
3031
|
+
const julianDay = NOAACalculator.getJulianDay(date.toPlainDate());
|
|
3032
|
+
const julianCenturies = NOAACalculator.getJulianCenturiesFromJulianDay(julianDay);
|
|
3033
|
+
const equationOfTime = NOAACalculator.getEquationOfTime(julianCenturies);
|
|
3034
|
+
let longitude = date.hour + 12 + (date.minute + equationOfTime + date.second / 60) / 60;
|
|
3035
|
+
longitude = -((longitude * 360) / 24) % 360;
|
|
3036
|
+
const hourAngleRad = degreesToRadians(lon - longitude);
|
|
3037
|
+
const declination = NOAACalculator.getSunDeclination(julianCenturies);
|
|
3038
|
+
const decRad = degreesToRadians(declination);
|
|
3039
|
+
const latRad = degreesToRadians(lat);
|
|
3040
|
+
return radiansToDegrees(Math.asin(Math.sin(latRad) * Math.sin(decRad) +
|
|
3041
|
+
Math.cos(latRad) * Math.cos(decRad) * Math.cos(hourAngleRad)));
|
|
3042
|
+
}
|
|
3043
|
+
/**
|
|
3044
|
+
* Return the <a href="http://en.wikipedia.org/wiki/Celestial_coordinate_system">Solar Azimuth</a> for the
|
|
3045
|
+
* horizontal coordinate system at the given location at the given time. Not corrected for altitude. True south is 0
|
|
3046
|
+
* degrees.
|
|
3047
|
+
*
|
|
3048
|
+
* @param {Temporal.ZonedDateTime} date
|
|
3049
|
+
* time of calculation
|
|
3050
|
+
* @param {number} latitude
|
|
3051
|
+
* latitude of location for calculation
|
|
3052
|
+
* @param {number} lon
|
|
3053
|
+
* longitude of location for calculation
|
|
3054
|
+
* @return {number}
|
|
3055
|
+
*/
|
|
3056
|
+
static getSolarAzimuth(date, latitude, lon) {
|
|
3057
|
+
const julianDay = NOAACalculator.getJulianDay(date.toPlainDate());
|
|
3058
|
+
const julianCenturies = NOAACalculator.getJulianCenturiesFromJulianDay(julianDay);
|
|
3059
|
+
const equationOfTime = NOAACalculator.getEquationOfTime(julianCenturies);
|
|
3060
|
+
let longitude = date.hour + 12 + (date.minute + equationOfTime + date.second / 60) / 60;
|
|
3061
|
+
longitude = -((longitude * 360) / 24) % 360;
|
|
3062
|
+
const hourAngleRad = degreesToRadians(lon - longitude);
|
|
3063
|
+
const declination = NOAACalculator.getSunDeclination(julianCenturies);
|
|
3064
|
+
const decRad = degreesToRadians(declination);
|
|
3065
|
+
const latRad = degreesToRadians(latitude);
|
|
3066
|
+
return (radiansToDegrees(Math.atan(Math.sin(hourAngleRad) /
|
|
3067
|
+
(Math.cos(hourAngleRad) * Math.sin(latRad) -
|
|
3068
|
+
Math.tan(decRad) * Math.cos(latRad)))) + 180);
|
|
3069
|
+
}
|
|
3070
|
+
/**
|
|
3071
|
+
* Return the <a href="http://en.wikipedia.org/wiki/Universal_Coordinated_Time">Universal Coordinated Time</a> (UTC)
|
|
3072
|
+
* of sunrise for the given day at the given location on earth
|
|
3073
|
+
* @private
|
|
3074
|
+
* @param julianDay
|
|
3075
|
+
* the Julian day
|
|
3076
|
+
* @param {number} latitude
|
|
3077
|
+
* the latitude of observer in degrees
|
|
3078
|
+
* @param {number} longitude
|
|
3079
|
+
* the longitude of observer in degrees
|
|
3080
|
+
* @param {number} zenith
|
|
3081
|
+
* the zenith
|
|
3082
|
+
* @return the time in minutes from zero UTC
|
|
3083
|
+
*/
|
|
3084
|
+
static getSunriseUTC(julianDay, latitude, longitude, zenith) {
|
|
3085
|
+
const julianCenturies = NOAACalculator.getJulianCenturiesFromJulianDay(julianDay);
|
|
3086
|
+
// Find the time of solar noon at the location, and use that declination. This is better than start of the
|
|
3087
|
+
// Julian day
|
|
3088
|
+
const noonmin = NOAACalculator.getSolarNoonUTC(julianCenturies, longitude);
|
|
3089
|
+
const tnoon = NOAACalculator.getJulianCenturiesFromJulianDay(julianDay + noonmin / 1440);
|
|
3090
|
+
// First pass to approximate sunrise (using solar noon)
|
|
3091
|
+
let eqTime = NOAACalculator.getEquationOfTime(tnoon);
|
|
3092
|
+
let solarDec = NOAACalculator.getSunDeclination(tnoon);
|
|
3093
|
+
let hourAngle = NOAACalculator.getSunHourAngleAtSunrise(latitude, solarDec, zenith);
|
|
3094
|
+
let delta = longitude - radiansToDegrees(hourAngle);
|
|
3095
|
+
let timeDiff = 4 * delta; // in minutes of time
|
|
3096
|
+
let timeUTC = 720 + timeDiff - eqTime; // in minutes
|
|
3097
|
+
// Second pass includes fractional Julian Day in gamma calc
|
|
3098
|
+
const newt = NOAACalculator.getJulianCenturiesFromJulianDay(NOAACalculator.getJulianDayFromJulianCenturies(julianCenturies) +
|
|
3099
|
+
timeUTC / 1440);
|
|
3100
|
+
eqTime = NOAACalculator.getEquationOfTime(newt);
|
|
3101
|
+
solarDec = NOAACalculator.getSunDeclination(newt);
|
|
3102
|
+
hourAngle = NOAACalculator.getSunHourAngleAtSunrise(latitude, solarDec, zenith);
|
|
3103
|
+
delta = longitude - radiansToDegrees(hourAngle);
|
|
3104
|
+
timeDiff = 4 * delta;
|
|
3105
|
+
timeUTC = 720 + timeDiff - eqTime; // in minutes
|
|
3106
|
+
return timeUTC;
|
|
3107
|
+
}
|
|
3108
|
+
/**
|
|
3109
|
+
* Return the <a href="http://en.wikipedia.org/wiki/Universal_Coordinated_Time">Universal Coordinated Time</a> (UTC)
|
|
3110
|
+
* of <a href="http://en.wikipedia.org/wiki/Noon#Solar_noon">solar noon</a> for the given day at the given location
|
|
3111
|
+
* on earth.
|
|
3112
|
+
* @private
|
|
3113
|
+
* @param julianCenturies
|
|
3114
|
+
* the number of Julian centuries since J2000.0
|
|
3115
|
+
* @param {number} longitude
|
|
3116
|
+
* the longitude of observer in degrees
|
|
3117
|
+
* @return the time in minutes from zero UTC
|
|
3118
|
+
*/
|
|
3119
|
+
static getSolarNoonUTC(julianCenturies, longitude) {
|
|
3120
|
+
// First pass uses approximate solar noon to calculate eqtime
|
|
3121
|
+
const tnoon = NOAACalculator.getJulianCenturiesFromJulianDay(NOAACalculator.getJulianDayFromJulianCenturies(julianCenturies) +
|
|
3122
|
+
longitude / 360);
|
|
3123
|
+
let eqTime = NOAACalculator.getEquationOfTime(tnoon);
|
|
3124
|
+
const solNoonUTC = 720 + longitude * 4 - eqTime; // min
|
|
3125
|
+
const newt = NOAACalculator.getJulianCenturiesFromJulianDay(NOAACalculator.getJulianDayFromJulianCenturies(julianCenturies) -
|
|
3126
|
+
0.5 +
|
|
3127
|
+
solNoonUTC / 1440);
|
|
3128
|
+
eqTime = NOAACalculator.getEquationOfTime(newt);
|
|
3129
|
+
return 720 + longitude * 4 - eqTime; // min
|
|
3130
|
+
}
|
|
3131
|
+
/**
|
|
3132
|
+
* Return the <a href="http://en.wikipedia.org/wiki/Universal_Coordinated_Time">Universal Coordinated Time</a> (UTC)
|
|
3133
|
+
* of sunset for the given day at the given location on earth
|
|
3134
|
+
* @private
|
|
3135
|
+
* @param julianDay
|
|
3136
|
+
* the Julian day
|
|
3137
|
+
* @param {number} latitude
|
|
3138
|
+
* the latitude of observer in degrees
|
|
3139
|
+
* @param {number} longitude
|
|
3140
|
+
* : longitude of observer in degrees
|
|
3141
|
+
* @param {number} zenith
|
|
3142
|
+
* the zenith
|
|
3143
|
+
* @return the time in minutes from zero Universal Coordinated Time (UTC)
|
|
3144
|
+
*/
|
|
3145
|
+
static getSunsetUTC(julianDay, latitude, longitude, zenith) {
|
|
3146
|
+
const julianCenturies = NOAACalculator.getJulianCenturiesFromJulianDay(julianDay);
|
|
3147
|
+
// Find the time of solar noon at the location, and use that declination. This is better than start of the
|
|
3148
|
+
// Julian day
|
|
3149
|
+
const noonmin = NOAACalculator.getSolarNoonUTC(julianCenturies, longitude);
|
|
3150
|
+
const tnoon = NOAACalculator.getJulianCenturiesFromJulianDay(julianDay + noonmin / 1440);
|
|
3151
|
+
// First calculates sunrise and approx length of day
|
|
3152
|
+
let eqTime = NOAACalculator.getEquationOfTime(tnoon);
|
|
3153
|
+
let solarDec = NOAACalculator.getSunDeclination(tnoon);
|
|
3154
|
+
let hourAngle = NOAACalculator.getSunHourAngleAtSunset(latitude, solarDec, zenith);
|
|
3155
|
+
let delta = longitude - radiansToDegrees(hourAngle);
|
|
3156
|
+
let timeDiff = 4 * delta;
|
|
3157
|
+
let timeUTC = 720 + timeDiff - eqTime;
|
|
3158
|
+
// Second pass includes fractional Julian Day in gamma calc
|
|
3159
|
+
const newt = NOAACalculator.getJulianCenturiesFromJulianDay(NOAACalculator.getJulianDayFromJulianCenturies(julianCenturies) +
|
|
3160
|
+
timeUTC / 1440);
|
|
3161
|
+
eqTime = NOAACalculator.getEquationOfTime(newt);
|
|
3162
|
+
solarDec = NOAACalculator.getSunDeclination(newt);
|
|
3163
|
+
hourAngle = NOAACalculator.getSunHourAngleAtSunset(latitude, solarDec, zenith);
|
|
3164
|
+
delta = longitude - radiansToDegrees(hourAngle);
|
|
3165
|
+
timeDiff = 4 * delta;
|
|
3166
|
+
timeUTC = 720 + timeDiff - eqTime; // in minutes
|
|
3167
|
+
return timeUTC;
|
|
3168
|
+
}
|
|
3169
|
+
}
|
|
3170
|
+
/**
|
|
3171
|
+
* The zenith of astronomical sunrise and sunset. The sun is 90° from the vertical 0°
|
|
3172
|
+
* @private
|
|
3173
|
+
*/
|
|
3174
|
+
NOAACalculator.GEOMETRIC_ZENITH = 90;
|
|
3175
|
+
/**
|
|
3176
|
+
* Default value for Sun's zenith and true rise/set Zenith (used in this class and subclasses) is the angle that the
|
|
3177
|
+
* center of the Sun makes to a line perpendicular to the Earth's surface. If the Sun were a point and the Earth
|
|
3178
|
+
* were without an atmosphere, true sunset and sunrise would correspond to a 90° zenith. Because the Sun is not
|
|
3179
|
+
* a point, and because the atmosphere refracts light, this 90° zenith does not, in fact, correspond to true
|
|
3180
|
+
* sunset or sunrise, instead the center of the Sun's disk must lie just below the horizon for the upper edge to be
|
|
3181
|
+
* obscured. This means that a zenith of just above 90° must be used. The Sun subtends an angle of 16 minutes of
|
|
3182
|
+
* arc (this can be changed via the {@link #setSunRadius(double)} method , and atmospheric refraction accounts for
|
|
3183
|
+
* 34 minutes or so (this can be changed via the {@link #setRefraction(double)} method), giving a total of 50
|
|
3184
|
+
* arcminutes. The total value for ZENITH is 90+(5/6) or 90.8333333° for true sunrise/sunset.
|
|
3185
|
+
*/
|
|
3186
|
+
// const ZENITH: number = GEOMETRIC_ZENITH + 5.0 / 6.0;
|
|
3187
|
+
/** Sun's zenith at civil twilight (96°). */
|
|
3188
|
+
NOAACalculator.CIVIL_ZENITH = 96;
|
|
3189
|
+
/** Sun's zenith at nautical twilight (102°). */
|
|
3190
|
+
NOAACalculator.NAUTICAL_ZENITH = 102;
|
|
3191
|
+
/** Sun's zenith at astronomical twilight (108°). */
|
|
3192
|
+
NOAACalculator.ASTRONOMICAL_ZENITH = 108;
|
|
3193
|
+
/**
|
|
3194
|
+
* The <a href="http://en.wikipedia.org/wiki/Julian_day">Julian day</a> of January 1, 2000
|
|
3195
|
+
* @private
|
|
3196
|
+
*/
|
|
3197
|
+
NOAACalculator.JULIAN_DAY_JAN_1_2000 = 2451545;
|
|
3198
|
+
/**
|
|
3199
|
+
* Julian days per century
|
|
3200
|
+
* @private
|
|
3201
|
+
*/
|
|
3202
|
+
NOAACalculator.JULIAN_DAYS_PER_CENTURY = 36525;
|
|
3203
|
+
|
|
3204
|
+
/*
|
|
3205
|
+
Hebcal - A Jewish Calendar Generator
|
|
3206
|
+
Copyright (c) 1994-2020 Danny Sadinoff
|
|
3207
|
+
Portions copyright Eyal Schachter and Michael J. Radwin
|
|
3208
|
+
|
|
3209
|
+
https://github.com/hebcal/hebcal-es6
|
|
3210
|
+
|
|
3211
|
+
This program is free software; you can redistribute it and/or
|
|
3212
|
+
modify it under the terms of the GNU General Public License
|
|
3213
|
+
as published by the Free Software Foundation; either version 2
|
|
3214
|
+
of the License, or (at your option) any later version.
|
|
3215
|
+
|
|
3216
|
+
This program is distributed in the hope that it will be useful,
|
|
3217
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
3218
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
3219
|
+
GNU General Public License for more details.
|
|
3220
|
+
|
|
3221
|
+
You should have received a copy of the GNU General Public License
|
|
3222
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
3223
|
+
*/
|
|
3224
|
+
const classicCities0 = [['Ashdod', 'IL', 31.79213, 34.64966, 'Asia/Jerusalem', 27], ['Atlanta', 'US', 33.749, -84.38798, 'America/New_York', 336], ['Austin', 'US', 30.26715, -97.74306, 'America/Chicago', 165], ['Baghdad', 'IQ', 33.34058, 44.40088, 'Asia/Baghdad', 41], ['Beer Sheva', 'IL', 31.25181, 34.7913, 'Asia/Jerusalem', 285], ['Berlin', 'DE', 52.52437, 13.41053, 'Europe/Berlin', 43], ['Baltimore', 'US', 39.29038, -76.61219, 'America/New_York', 35], ['Bogota', 'CO', 4.60971, -74.08175, 'America/Bogota', 2582], ['Boston', 'US', 42.35843, -71.05977, 'America/New_York', 38], ['Budapest', 'HU', 47.49801, 19.03991, 'Europe/Budapest', 104], ['Buenos Aires', 'AR', -34.61315, -58.37723, 'America/Argentina/Buenos_Aires', 31], ['Buffalo', 'US', 42.88645, -78.87837, 'America/New_York', 191], ['Chicago', 'US', 41.85003, -87.65005, 'America/Chicago', 180], ['Cincinnati', 'US', 39.162, -84.45689, 'America/New_York', 267], ['Cleveland', 'US', 41.4995, -81.69541, 'America/New_York', 204], ['Dallas', 'US', 32.78306, -96.80667, 'America/Chicago', 139], ['Denver', 'US', 39.73915, -104.9847, 'America/Denver', 1636], ['Detroit', 'US', 42.33143, -83.04575, 'America/Detroit', 192], ['Eilat', 'IL', 29.55805, 34.94821, 'Asia/Jerusalem', 63], ['Gibraltar', 'GI', 36.14474, -5.35257, 'Europe/Gibraltar', 11], ['Haifa', 'IL', 32.81841, 34.9885, 'Asia/Jerusalem', 40], ['Hawaii', 'US', 21.30694, -157.85833, 'Pacific/Honolulu', 18], ['Helsinki', 'FI', 60.16952, 24.93545, 'Europe/Helsinki', 26], ['Houston', 'US', 29.76328, -95.36327, 'America/Chicago', 30], ['Jerusalem', 'IL', 31.76904, 35.21633, 'Asia/Jerusalem', 786], ['Johannesburg', 'ZA', -26.20227, 28.04363, 'Africa/Johannesburg', 1767], ['Kiev', 'UA', 50.45466, 30.5238, 'Europe/Kiev', 187], ['La Paz', 'BO', -16.5, -68.15, 'America/La_Paz', 3782], ['Livingston', 'US', 40.79593, -74.31487, 'America/New_York', 98], ['Las Vegas', 'US', 36.17497, -115.13722, 'America/Los_Angeles', 613], ['London', 'GB', 51.50853, -0.12574, 'Europe/London', 25], ['Los Angeles', 'US', 34.05223, -118.24368, 'America/Los_Angeles', 96], ['Marseilles', 'FR', 43.29695, 5.38107, 'Europe/Paris', 28], ['Miami', 'US', 25.77427, -80.19366, 'America/New_York', 25], ['Minneapolis', 'US', 44.97997, -93.26384, 'America/Chicago', 262], ['Melbourne', 'AU', -37.814, 144.96332, 'Australia/Melbourne', 25], ['Mexico City', 'MX', 19.42847, -99.12766, 'America/Mexico_City', 2240], ['Montreal', 'CA', 45.50884, -73.58781, 'America/Toronto', 216], ['Moscow', 'RU', 55.75222, 37.61556, 'Europe/Moscow', 144], ['New York', 'US', 40.71427, -74.00597, 'America/New_York', 57], ['Omaha', 'US', 41.25861, -95.93779, 'America/Chicago', 315], ['Ottawa', 'CA', 45.41117, -75.69812, 'America/Toronto', 71], ['Panama City', 'PA', 8.9936, -79.51973, 'America/Panama', 17], ['Paris', 'FR', 48.85341, 2.3488, 'Europe/Paris', 42], ['Pawtucket', 'US', 41.87871, -71.38256, 'America/New_York', 0],
|
|
3225
|
+
// -11
|
|
3226
|
+
['Petach Tikvah', 'IL', 32.08707, 34.88747, 'Asia/Jerusalem', 54], ['Philadelphia', 'US', 39.95233, -75.16379, 'America/New_York', 8], ['Phoenix', 'US', 33.44838, -112.07404, 'America/Phoenix', 366], ['Pittsburgh', 'US', 40.44062, -79.99589, 'America/New_York', 239], ['Providence', 'US', 41.82399, -71.41283, 'America/New_York', 0],
|
|
3227
|
+
// -15
|
|
3228
|
+
['Portland', 'US', 45.52345, -122.67621, 'America/Los_Angeles', 15], ['Saint Louis', 'US', 38.62727, -90.19789, 'America/Chicago', 149], ['Saint Petersburg', 'RU', 59.93863, 30.31413, 'Europe/Moscow', 11], ['San Diego', 'US', 32.71533, -117.15726, 'America/Los_Angeles', 20], ['San Francisco', 'US', 37.77493, -122.41942, 'America/Los_Angeles', 28], ['Sao Paulo', 'BR', -23.5475, -46.63611, 'America/Sao_Paulo', 769], ['Seattle', 'US', 47.60621, -122.33207, 'America/Los_Angeles', 56], ['Sydney', 'AU', -33.86785, 151.20732, 'Australia/Sydney', 58], ['Tel Aviv', 'IL', 32.08088, 34.78057, 'Asia/Jerusalem', 15], ['Tiberias', 'IL', 32.79221, 35.53124, 'Asia/Jerusalem', 0],
|
|
3229
|
+
// -140
|
|
3230
|
+
['Toronto', 'CA', 43.70011, -79.4163, 'America/Toronto', 175], ['Vancouver', 'CA', 49.24966, -123.11934, 'America/Vancouver', 70], ['White Plains', 'US', 41.03399, -73.76291, 'America/New_York', 82], ['Washington DC', 'US', 38.89511, -77.03637, 'America/New_York', 6], ['Worcester', 'US', 42.26259, -71.80229, 'America/New_York', 164]];
|
|
3231
|
+
const classicCities = new Map();
|
|
3232
|
+
|
|
3233
|
+
// Zip-Codes.com TimeZone IDs
|
|
3234
|
+
const ZIPCODES_TZ_MAP = {
|
|
3235
|
+
'0': 'UTC',
|
|
3236
|
+
'4': 'America/Puerto_Rico',
|
|
3237
|
+
// Atlantic (GMT -04:00)
|
|
3238
|
+
'5': 'America/New_York',
|
|
3239
|
+
// Eastern (GMT -05:00)
|
|
3240
|
+
'6': 'America/Chicago',
|
|
3241
|
+
// Central (GMT -06:00)
|
|
3242
|
+
'7': 'America/Denver',
|
|
3243
|
+
// Mountain (GMT -07:00)
|
|
3244
|
+
'8': 'America/Los_Angeles',
|
|
3245
|
+
// Pacific (GMT -08:00)
|
|
3246
|
+
'9': 'America/Anchorage',
|
|
3247
|
+
// Alaska (GMT -09:00)
|
|
3248
|
+
'10': 'Pacific/Honolulu',
|
|
3249
|
+
// Hawaii-Aleutian Islands (GMT -10:00)
|
|
3250
|
+
'11': 'Pacific/Pago_Pago',
|
|
3251
|
+
// American Samoa (GMT -11:00)
|
|
3252
|
+
'13': 'Pacific/Funafuti',
|
|
3253
|
+
// Marshall Islands (GMT +12:00)
|
|
3254
|
+
'14': 'Pacific/Guam',
|
|
3255
|
+
// Guam (GMT +10:00)
|
|
3256
|
+
'15': 'Pacific/Palau',
|
|
3257
|
+
// Palau (GMT +9:00)
|
|
3258
|
+
'16': 'Pacific/Chuuk' // Micronesia (GMT +11:00)
|
|
3259
|
+
};
|
|
3260
|
+
|
|
3261
|
+
/** @private */
|
|
3262
|
+
const timeFormatCache = new Map();
|
|
3263
|
+
|
|
3264
|
+
/**
|
|
3265
|
+
* Gets a 24-hour time formatter (e.g. 07:41 or 20:03) from cache
|
|
3266
|
+
* or makes a new one if needed
|
|
3267
|
+
* @private
|
|
3268
|
+
* @param {string} tzid
|
|
3269
|
+
* @return {Intl.DateTimeFormat}
|
|
3270
|
+
*/
|
|
3271
|
+
function getFormatter$1(tzid) {
|
|
3272
|
+
const fmt = timeFormatCache.get(tzid);
|
|
3273
|
+
if (fmt) return fmt;
|
|
3274
|
+
const f = new Intl.DateTimeFormat('en-US', {
|
|
3275
|
+
timeZone: tzid,
|
|
3276
|
+
hour: 'numeric',
|
|
3277
|
+
minute: 'numeric',
|
|
3278
|
+
hour12: false
|
|
3279
|
+
});
|
|
3280
|
+
timeFormatCache.set(tzid, f);
|
|
3281
|
+
return f;
|
|
3282
|
+
}
|
|
3283
|
+
|
|
3284
|
+
/** Class representing Location */
|
|
3285
|
+
class Location extends GeoLocation {
|
|
3286
|
+
/**
|
|
3287
|
+
* Initialize a Location instance
|
|
3288
|
+
* @param {number} latitude - Latitude as a decimal, valid range -90 thru +90 (e.g. 41.85003)
|
|
3289
|
+
* @param {number} longitude - Longitude as a decimal, valid range -180 thru +180 (e.g. -87.65005)
|
|
3290
|
+
* @param {boolean} il - in Israel (true) or Diaspora (false)
|
|
3291
|
+
* @param {string} tzid - Olson timezone ID, e.g. "America/Chicago"
|
|
3292
|
+
* @param {string} cityName - optional descriptive city name
|
|
3293
|
+
* @param {string} countryCode - ISO 3166 alpha-2 country code (e.g. "FR")
|
|
3294
|
+
* @param {string} [geoid] - optional string or numeric geographic ID
|
|
3295
|
+
* @param {number} [elevation] - in meters (default `0`)
|
|
3296
|
+
*/
|
|
3297
|
+
constructor(latitude, longitude, il, tzid, cityName, countryCode, geoid, elevation) {
|
|
3298
|
+
const lat = typeof latitude === 'number' ? latitude : parseFloat(latitude);
|
|
3299
|
+
if (isNaN(lat) || lat < -90 || lat > 90) {
|
|
3300
|
+
throw new RangeError(`Latitude ${latitude} out of range [-90,90]`);
|
|
3301
|
+
}
|
|
3302
|
+
const long = typeof longitude === 'number' ? longitude : parseFloat(longitude);
|
|
3303
|
+
if (isNaN(long) || long < -180 || long > 180) {
|
|
3304
|
+
throw new RangeError(`Longitude ${longitude} out of range [-180,180]`);
|
|
3305
|
+
}
|
|
3306
|
+
const elev = typeof elevation === 'number' && elevation > 0 ? elevation : 0;
|
|
3307
|
+
super(cityName, lat, long, elev, tzid);
|
|
3308
|
+
this.il = Boolean(il);
|
|
3309
|
+
this.cc = countryCode;
|
|
3310
|
+
this.geoid = geoid;
|
|
3311
|
+
}
|
|
3312
|
+
|
|
3313
|
+
/** @return {boolean} */
|
|
3314
|
+
getIsrael() {
|
|
3315
|
+
return this.il;
|
|
3316
|
+
}
|
|
3317
|
+
|
|
3318
|
+
/** @return {string} */
|
|
3319
|
+
getName() {
|
|
3320
|
+
return this.getLocationName();
|
|
3321
|
+
}
|
|
3322
|
+
|
|
3323
|
+
/**
|
|
3324
|
+
* Returns the location name, up to the first comma
|
|
3325
|
+
* @return {string}
|
|
3326
|
+
*/
|
|
3327
|
+
getShortName() {
|
|
3328
|
+
const name = this.getLocationName();
|
|
3329
|
+
if (!name) return name;
|
|
3330
|
+
const comma = name.indexOf(', ');
|
|
3331
|
+
if (comma === -1) return name;
|
|
3332
|
+
if (this.cc === 'US' && name[comma + 2] === 'D') {
|
|
3333
|
+
if (name[comma + 3] === 'C') {
|
|
3334
|
+
return name.substring(0, comma + 4);
|
|
3335
|
+
} else if (name[comma + 3] === '.' && name[comma + 4] === 'C') {
|
|
3336
|
+
return name.substring(0, comma + 6);
|
|
3337
|
+
}
|
|
3338
|
+
}
|
|
3339
|
+
return name.substring(0, comma);
|
|
3340
|
+
}
|
|
3341
|
+
|
|
3342
|
+
/** @return {string} */
|
|
3343
|
+
getCountryCode() {
|
|
3344
|
+
return this.cc;
|
|
3345
|
+
}
|
|
3346
|
+
|
|
3347
|
+
/** @return {string} */
|
|
3348
|
+
getTzid() {
|
|
3349
|
+
return this.getTimeZone();
|
|
3350
|
+
}
|
|
3351
|
+
|
|
3352
|
+
/**
|
|
3353
|
+
* Gets a 24-hour time formatter (e.g. 07:41 or 20:03) for this location
|
|
3354
|
+
* @return {Intl.DateTimeFormat}
|
|
3355
|
+
*/
|
|
3356
|
+
getTimeFormatter() {
|
|
3357
|
+
return getFormatter$1(this.getTimeZone());
|
|
3358
|
+
}
|
|
3359
|
+
|
|
3360
|
+
/** @return {string} */
|
|
3361
|
+
getGeoId() {
|
|
3362
|
+
return this.geoid;
|
|
3363
|
+
}
|
|
3364
|
+
|
|
3365
|
+
/**
|
|
3366
|
+
* Creates a location object from one of 60 "classic" Hebcal city names.
|
|
3367
|
+
* The following city names are supported:
|
|
3368
|
+
* 'Ashdod', 'Atlanta', 'Austin', 'Baghdad', 'Beer Sheva',
|
|
3369
|
+
* 'Berlin', 'Baltimore', 'Bogota', 'Boston', 'Budapest',
|
|
3370
|
+
* 'Buenos Aires', 'Buffalo', 'Chicago', 'Cincinnati', 'Cleveland',
|
|
3371
|
+
* 'Dallas', 'Denver', 'Detroit', 'Eilat', 'Gibraltar', 'Haifa',
|
|
3372
|
+
* 'Hawaii', 'Helsinki', 'Houston', 'Jerusalem', 'Johannesburg',
|
|
3373
|
+
* 'Kiev', 'La Paz', 'Livingston', 'Las Vegas', 'London', 'Los Angeles',
|
|
3374
|
+
* 'Marseilles', 'Miami', 'Minneapolis', 'Melbourne', 'Mexico City',
|
|
3375
|
+
* 'Montreal', 'Moscow', 'New York', 'Omaha', 'Ottawa', 'Panama City',
|
|
3376
|
+
* 'Paris', 'Pawtucket', 'Petach Tikvah', 'Philadelphia', 'Phoenix',
|
|
3377
|
+
* 'Pittsburgh', 'Providence', 'Portland', 'Saint Louis', 'Saint Petersburg',
|
|
3378
|
+
* 'San Diego', 'San Francisco', 'Sao Paulo', 'Seattle', 'Sydney',
|
|
3379
|
+
* 'Tel Aviv', 'Tiberias', 'Toronto', 'Vancouver', 'White Plains',
|
|
3380
|
+
* 'Washington DC', 'Worcester'
|
|
3381
|
+
* @param {string} name
|
|
3382
|
+
* @return {Location}
|
|
3383
|
+
*/
|
|
3384
|
+
static lookup(name) {
|
|
3385
|
+
return classicCities.get(name.toLowerCase());
|
|
3386
|
+
}
|
|
3387
|
+
|
|
3388
|
+
/** @return {string} */
|
|
3389
|
+
toString() {
|
|
3390
|
+
return JSON.stringify(this);
|
|
3391
|
+
}
|
|
3392
|
+
|
|
3393
|
+
/**
|
|
3394
|
+
* Converts legacy Hebcal timezone to a standard Olson tzid.
|
|
3395
|
+
* @param {number} tz integer, GMT offset in hours
|
|
3396
|
+
* @param {string} dst 'none', 'eu', 'usa', or 'israel'
|
|
3397
|
+
* @return {string}
|
|
3398
|
+
*/
|
|
3399
|
+
static legacyTzToTzid(tz, dst) {
|
|
3400
|
+
tz = +tz;
|
|
3401
|
+
if (dst == 'none') {
|
|
3402
|
+
if (tz == 0) {
|
|
3403
|
+
return 'UTC';
|
|
3404
|
+
} else {
|
|
3405
|
+
const plus = tz > 0 ? '+' : '';
|
|
3406
|
+
return `Etc/GMT${plus}${tz}`;
|
|
3407
|
+
}
|
|
3408
|
+
} else if (tz == 2 && dst == 'israel') {
|
|
3409
|
+
return 'Asia/Jerusalem';
|
|
3410
|
+
} else if (dst == 'eu') {
|
|
3411
|
+
switch (tz) {
|
|
3412
|
+
case -2:
|
|
3413
|
+
return 'Atlantic/Cape_Verde';
|
|
3414
|
+
case -1:
|
|
3415
|
+
return 'Atlantic/Azores';
|
|
3416
|
+
case 0:
|
|
3417
|
+
return 'Europe/London';
|
|
3418
|
+
case 1:
|
|
3419
|
+
return 'Europe/Paris';
|
|
3420
|
+
case 2:
|
|
3421
|
+
return 'Europe/Athens';
|
|
3422
|
+
}
|
|
3423
|
+
} else if (dst == 'usa') {
|
|
3424
|
+
return ZIPCODES_TZ_MAP[String(tz * -1)];
|
|
3425
|
+
}
|
|
3426
|
+
return undefined;
|
|
3427
|
+
}
|
|
3428
|
+
|
|
3429
|
+
/**
|
|
3430
|
+
* Converts timezone info from Zip-Codes.com to a standard Olson tzid.
|
|
3431
|
+
* @example
|
|
3432
|
+
* Location.getUsaTzid('AZ', 7, 'Y') // 'America/Denver'
|
|
3433
|
+
* @param {string} state two-letter all-caps US state abbreviation like 'CA'
|
|
3434
|
+
* @param {number} tz positive number, 5=America/New_York, 8=America/Los_Angeles
|
|
3435
|
+
* @param {string} dst single char 'Y' or 'N'
|
|
3436
|
+
* @return {string}
|
|
3437
|
+
*/
|
|
3438
|
+
static getUsaTzid(state, tz, dst) {
|
|
3439
|
+
if (tz == 10 && state == 'AK') {
|
|
3440
|
+
return 'America/Adak';
|
|
3441
|
+
} else if (tz == 7 && state == 'AZ') {
|
|
3442
|
+
return dst == 'Y' ? 'America/Denver' : 'America/Phoenix';
|
|
3443
|
+
} else {
|
|
3444
|
+
return ZIPCODES_TZ_MAP[tz];
|
|
3445
|
+
}
|
|
3446
|
+
}
|
|
3447
|
+
|
|
3448
|
+
/**
|
|
3449
|
+
* Adds a location name for `Location.lookup()` only if the name isn't
|
|
3450
|
+
* already being used. Returns `false` if the name is already taken
|
|
3451
|
+
* and `true` if successfully added.
|
|
3452
|
+
* @param {string} cityName
|
|
3453
|
+
* @param {Location} location
|
|
3454
|
+
* @return {boolean}
|
|
3455
|
+
*/
|
|
3456
|
+
static addLocation(cityName, location) {
|
|
3457
|
+
const name = cityName.toLowerCase();
|
|
3458
|
+
if (classicCities.has(name)) {
|
|
3459
|
+
return false;
|
|
3460
|
+
}
|
|
3461
|
+
classicCities.set(name, location);
|
|
3462
|
+
return true;
|
|
3463
|
+
}
|
|
3464
|
+
}
|
|
3465
|
+
classicCities0.forEach(city => {
|
|
3466
|
+
const location = new Location(city[2], city[3], city[1] == 'IL', city[4], city[0], city[1], undefined, city[5]);
|
|
3467
|
+
Location.addLocation(location.getName(), location);
|
|
3468
|
+
});
|
|
3469
|
+
|
|
3470
|
+
const _formatters = new Map();
|
|
3471
|
+
|
|
3472
|
+
/**
|
|
3473
|
+
* @private
|
|
3474
|
+
* @param {string} tzid
|
|
3475
|
+
* @return {Intl.DateTimeFormat}
|
|
3476
|
+
*/
|
|
3477
|
+
function getFormatter(tzid) {
|
|
3478
|
+
const fmt = _formatters.get(tzid);
|
|
3479
|
+
if (fmt) return fmt;
|
|
3480
|
+
const f = new Intl.DateTimeFormat('en-US', {
|
|
3481
|
+
year: 'numeric',
|
|
3482
|
+
month: '2-digit',
|
|
3483
|
+
day: '2-digit',
|
|
3484
|
+
hour: '2-digit',
|
|
3485
|
+
minute: '2-digit',
|
|
3486
|
+
second: '2-digit',
|
|
3487
|
+
hour12: false,
|
|
3488
|
+
timeZone: tzid
|
|
3489
|
+
});
|
|
3490
|
+
_formatters.set(tzid, f);
|
|
3491
|
+
return f;
|
|
3492
|
+
}
|
|
3493
|
+
const dateFormatRegex = /^(\d+).(\d+).(\d+),?\s+(\d+).(\d+).(\d+)/;
|
|
3494
|
+
|
|
3495
|
+
/**
|
|
3496
|
+
* @private
|
|
3497
|
+
* @param {string} tzid
|
|
3498
|
+
* @param {Date} date
|
|
3499
|
+
* @return {string}
|
|
3500
|
+
*/
|
|
3501
|
+
function getPseudoISO(tzid, date) {
|
|
3502
|
+
const str = getFormatter(tzid).format(date);
|
|
3503
|
+
const m = dateFormatRegex.exec(str);
|
|
3504
|
+
let hour = m[4];
|
|
3505
|
+
if (hour == '24') hour = '00';
|
|
3506
|
+
m[3] = pad4(m[3]);
|
|
3507
|
+
return `${m[3]}-${m[1]}-${m[2]}T${hour}:${m[5]}:${m[6]}Z`;
|
|
3508
|
+
}
|
|
3509
|
+
|
|
3510
|
+
/**
|
|
3511
|
+
* @private
|
|
3512
|
+
* @param {string} tzid
|
|
3513
|
+
* @param {Date} date
|
|
3514
|
+
* @return {number}
|
|
3515
|
+
*/
|
|
3516
|
+
function getTimezoneOffset(tzid, date) {
|
|
3517
|
+
const utcStr = getPseudoISO('UTC', date);
|
|
3518
|
+
const localStr = getPseudoISO(tzid, date);
|
|
3519
|
+
const diffMs = new Date(utcStr).getTime() - new Date(localStr).getTime();
|
|
3520
|
+
return Math.ceil(diffMs / 1000 / 60);
|
|
3521
|
+
}
|
|
3522
|
+
|
|
3523
|
+
/**
|
|
3524
|
+
* @private
|
|
3525
|
+
* @param {number} number
|
|
3526
|
+
* @return {string}
|
|
3527
|
+
*/
|
|
3528
|
+
function pad4(number) {
|
|
2392
3529
|
if (number < 0) {
|
|
2393
3530
|
return '-00' + pad4(-number);
|
|
2394
3531
|
} else if (number < 10) {
|
|
@@ -2414,25 +3551,18 @@ function pad2(number) {
|
|
|
2414
3551
|
}
|
|
2415
3552
|
|
|
2416
3553
|
/**
|
|
2417
|
-
* @
|
|
2418
|
-
* @
|
|
2419
|
-
* @
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
* @property {Date} sunset
|
|
2430
|
-
* @property {Date} sunsetStart
|
|
2431
|
-
* @property {Date} alotHaShachar
|
|
2432
|
-
* @property {Date} misheyakir
|
|
2433
|
-
* @property {Date} misheyakirMachmir
|
|
2434
|
-
* @property {Date} tzeit
|
|
2435
|
-
*/
|
|
3554
|
+
* @private
|
|
3555
|
+
* @param {Temporal.ZonedDateTime} zdt
|
|
3556
|
+
* @return {Date}
|
|
3557
|
+
*/
|
|
3558
|
+
function zdtToDate(zdt) {
|
|
3559
|
+
if (zdt === null) {
|
|
3560
|
+
return new Date(NaN);
|
|
3561
|
+
}
|
|
3562
|
+
const res = new Date(zdt.epochMilliseconds);
|
|
3563
|
+
res.setMilliseconds(0);
|
|
3564
|
+
return res;
|
|
3565
|
+
}
|
|
2436
3566
|
|
|
2437
3567
|
/**
|
|
2438
3568
|
* Calculate halachic times (zmanim / זְמַנִּים) for a given day and location.
|
|
@@ -2450,62 +3580,33 @@ function pad2(number) {
|
|
|
2450
3580
|
* https://gml.noaa.gov/grad/solcalc/calcdetails.html
|
|
2451
3581
|
*
|
|
2452
3582
|
* @example
|
|
2453
|
-
* const {Zmanim} = require('@hebcal/core');
|
|
3583
|
+
* const {GeoLocation, Zmanim} = require('@hebcal/core');
|
|
2454
3584
|
* const latitude = 41.822232;
|
|
2455
3585
|
* const longitude = -71.448292;
|
|
3586
|
+
* const tzid = 'America/New_York';
|
|
2456
3587
|
* const friday = new Date(2023, 8, 8);
|
|
2457
|
-
* const
|
|
3588
|
+
* const gloc = new GeoLocation(null, latitude, longitude, 0, tzid);
|
|
3589
|
+
* const zmanim = new Zmanim(gloc, friday);
|
|
2458
3590
|
* const candleLighting = zmanim.sunsetOffset(-18, true);
|
|
2459
|
-
* const timeStr = Zmanim.formatISOWithTimeZone(
|
|
3591
|
+
* const timeStr = Zmanim.formatISOWithTimeZone(tzid, candleLighting);
|
|
2460
3592
|
*/
|
|
2461
3593
|
class Zmanim {
|
|
2462
3594
|
/**
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
* @param {number} longitude
|
|
2468
|
-
*/
|
|
2469
|
-
constructor(date, latitude, longitude) {
|
|
2470
|
-
if (typeof latitude !== 'number') throw new TypeError('Invalid latitude');
|
|
2471
|
-
if (typeof longitude !== 'number') throw new TypeError('Invalid longitude');
|
|
2472
|
-
if (latitude < -90 || latitude > 90) {
|
|
2473
|
-
throw new RangeError(`Latitude ${latitude} out of range [-90,90]`);
|
|
2474
|
-
}
|
|
2475
|
-
if (longitude < -180 || longitude > 180) {
|
|
2476
|
-
throw new RangeError(`Longitude ${longitude} out of range [-180,180]`);
|
|
2477
|
-
}
|
|
2478
|
-
const dt = isDate(date) ? date : HDate.isHDate(date) ? date.greg() : throwTypeError(`invalid date: ${date}`);
|
|
2479
|
-
this.date = dt;
|
|
2480
|
-
this.solarCalc = new SolarCalc(this.date, latitude, longitude);
|
|
2481
|
-
this.sun = this.solarCalc.sun;
|
|
2482
|
-
this.latitude = latitude;
|
|
2483
|
-
this.longitude = longitude;
|
|
2484
|
-
}
|
|
2485
|
-
/**
|
|
2486
|
-
* @deprecated
|
|
2487
|
-
* @return {ZmanimTimesResult}
|
|
3595
|
+
* Initialize a Zmanim instance.
|
|
3596
|
+
* @param {GeoLocation} gloc GeoLocation including latitude, longitude, and timezone
|
|
3597
|
+
* @param {Date|HDate} date Regular or Hebrew Date. If `date` is a regular `Date`,
|
|
3598
|
+
* hours, minutes, seconds and milliseconds are ignored.
|
|
2488
3599
|
*/
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
nauticalDusk: this.solarCalc.nauticalDusk,
|
|
2500
|
-
nightEnd: this.solarCalc.nightEnd,
|
|
2501
|
-
night: this.solarCalc.nightStart,
|
|
2502
|
-
goldenHourEnd: this.solarCalc.goldenHourEnd,
|
|
2503
|
-
goldenHour: this.solarCalc.goldenHourStart,
|
|
2504
|
-
alotHaShachar: this.alotHaShachar(),
|
|
2505
|
-
misheyakir: this.misheyakir(),
|
|
2506
|
-
misheyakirMachmir: this.misheyakirMachmir(),
|
|
2507
|
-
tzeit: this.tzeit()
|
|
2508
|
-
};
|
|
3600
|
+
constructor(gloc, date) {
|
|
3601
|
+
const dt = greg.isDate(date) ? date : HDate.isHDate(date) ? date.greg() : throwTypeError(`invalid date: ${date}`);
|
|
3602
|
+
this.date = dt;
|
|
3603
|
+
this.gloc = gloc;
|
|
3604
|
+
const plainDate = s.PlainDate.from({
|
|
3605
|
+
year: dt.getFullYear(),
|
|
3606
|
+
month: dt.getMonth() + 1,
|
|
3607
|
+
day: dt.getDate()
|
|
3608
|
+
});
|
|
3609
|
+
this.noaa = new NOAACalculator(gloc, plainDate);
|
|
2509
3610
|
}
|
|
2510
3611
|
/**
|
|
2511
3612
|
* Convenience function to get the time when sun is above or below the horizon
|
|
@@ -2515,637 +3616,309 @@ class Zmanim {
|
|
|
2515
3616
|
* @return {Date}
|
|
2516
3617
|
*/
|
|
2517
3618
|
timeAtAngle(angle, rising) {
|
|
2518
|
-
|
|
3619
|
+
const offsetZenith = 90 + angle;
|
|
3620
|
+
const zdt = rising ? this.noaa.getSunriseOffsetByDegrees(offsetZenith) : this.noaa.getSunsetOffsetByDegrees(offsetZenith);
|
|
3621
|
+
return zdtToDate(zdt);
|
|
2519
3622
|
}
|
|
2520
3623
|
/**
|
|
2521
3624
|
* Upper edge of the Sun appears over the eastern horizon in the morning (0.833° above horizon)
|
|
2522
3625
|
* @return {Date}
|
|
2523
3626
|
*/
|
|
2524
3627
|
sunrise() {
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
/**
|
|
2528
|
-
* When the upper edge of the Sun disappears below the horizon (0.833° below horizon)
|
|
2529
|
-
* @return {Date}
|
|
2530
|
-
*/
|
|
2531
|
-
sunset() {
|
|
2532
|
-
return this.sun.timeAtAngle(0.833333, false);
|
|
2533
|
-
}
|
|
2534
|
-
/**
|
|
2535
|
-
* Civil dawn; Sun is 6° below the horizon in the morning
|
|
2536
|
-
* @return {Date}
|
|
2537
|
-
*/
|
|
2538
|
-
dawn() {
|
|
2539
|
-
return this.solarCalc.dawn;
|
|
2540
|
-
}
|
|
2541
|
-
/**
|
|
2542
|
-
* Civil dusk; Sun is 6° below the horizon in the evening
|
|
2543
|
-
* @return {Date}
|
|
2544
|
-
*/
|
|
2545
|
-
dusk() {
|
|
2546
|
-
return this.solarCalc.dusk;
|
|
2547
|
-
}
|
|
2548
|
-
/** @return {number} */
|
|
2549
|
-
hour() {
|
|
2550
|
-
return (this.sunset() - this.sunrise()) / 12; // ms in hour
|
|
2551
|
-
}
|
|
2552
|
-
/** @return {number} */
|
|
2553
|
-
hourMins() {
|
|
2554
|
-
// hour in ms / (1000 ms in s * 60 s in m) = mins in halachic hour
|
|
2555
|
-
return this.hour() / (1000 * 60);
|
|
2556
|
-
}
|
|
2557
|
-
/** @return {Date} */
|
|
2558
|
-
gregEve() {
|
|
2559
|
-
const prev = new Date(this.date);
|
|
2560
|
-
prev.setDate(prev.getDate() - 1);
|
|
2561
|
-
const zman = new Zmanim(prev, this.latitude, this.longitude);
|
|
2562
|
-
return zman.sunset();
|
|
2563
|
-
}
|
|
2564
|
-
/** @return {number} */
|
|
2565
|
-
nightHour() {
|
|
2566
|
-
return (this.sunrise() - this.gregEve()) / 12; // ms in hour
|
|
2567
|
-
}
|
|
2568
|
-
/** @return {number} */
|
|
2569
|
-
nightHourMins() {
|
|
2570
|
-
// hour in ms / (1000 ms in s * 60 s in m) = mins in halachic hour
|
|
2571
|
-
return this.nightHour() / (1000 * 60);
|
|
2572
|
-
}
|
|
2573
|
-
/**
|
|
2574
|
-
* @param {number} hours
|
|
2575
|
-
* @return {Date}
|
|
2576
|
-
*/
|
|
2577
|
-
hourOffset(hours) {
|
|
2578
|
-
return new Date(this.sunrise().getTime() + this.hour() * hours);
|
|
2579
|
-
}
|
|
2580
|
-
/**
|
|
2581
|
-
* Midday – Chatzot; Sunrise plus 6 halachic hours
|
|
2582
|
-
* @return {Date}
|
|
2583
|
-
*/
|
|
2584
|
-
chatzot() {
|
|
2585
|
-
return this.hourOffset(6);
|
|
2586
|
-
}
|
|
2587
|
-
/**
|
|
2588
|
-
* Midnight – Chatzot; Sunset plus 6 halachic hours
|
|
2589
|
-
* @return {Date}
|
|
2590
|
-
*/
|
|
2591
|
-
chatzotNight() {
|
|
2592
|
-
return new Date(this.sunrise().getTime() - this.nightHour() * 6);
|
|
2593
|
-
}
|
|
2594
|
-
/**
|
|
2595
|
-
* Dawn – Alot haShachar; Sun is 16.1° below the horizon in the morning
|
|
2596
|
-
* @return {Date}
|
|
2597
|
-
*/
|
|
2598
|
-
alotHaShachar() {
|
|
2599
|
-
return this.sun.timeAtAngle(16.1, true);
|
|
2600
|
-
}
|
|
2601
|
-
/**
|
|
2602
|
-
* Earliest talis & tefillin – Misheyakir; Sun is 11.5° below the horizon in the morning
|
|
2603
|
-
* @return {Date}
|
|
2604
|
-
*/
|
|
2605
|
-
misheyakir() {
|
|
2606
|
-
return this.sun.timeAtAngle(11.5, true);
|
|
2607
|
-
}
|
|
2608
|
-
/**
|
|
2609
|
-
* Earliest talis & tefillin – Misheyakir Machmir; Sun is 10.2° below the horizon in the morning
|
|
2610
|
-
* @return {Date}
|
|
2611
|
-
*/
|
|
2612
|
-
misheyakirMachmir() {
|
|
2613
|
-
return this.sun.timeAtAngle(10.2, true);
|
|
3628
|
+
const zdt = this.noaa.getSunrise();
|
|
3629
|
+
return zdtToDate(zdt);
|
|
2614
3630
|
}
|
|
2615
3631
|
/**
|
|
2616
|
-
*
|
|
2617
|
-
* @return {Date}
|
|
2618
|
-
*/
|
|
2619
|
-
sofZmanShma() {
|
|
2620
|
-
// Gra
|
|
2621
|
-
return this.hourOffset(3);
|
|
2622
|
-
}
|
|
2623
|
-
/**
|
|
2624
|
-
* Latest Shacharit (Gra); Sunrise plus 4 halachic hours, according to the Gra
|
|
2625
|
-
* @return {Date}
|
|
2626
|
-
*/
|
|
2627
|
-
sofZmanTfilla() {
|
|
2628
|
-
// Gra
|
|
2629
|
-
return this.hourOffset(4);
|
|
2630
|
-
}
|
|
2631
|
-
/**
|
|
2632
|
-
* Latest Shema (MGA); Sunrise plus 3 halachic hours, according to Magen Avraham
|
|
2633
|
-
* @return {Date}
|
|
2634
|
-
*/
|
|
2635
|
-
sofZmanShmaMGA() {
|
|
2636
|
-
// Magen Avraham
|
|
2637
|
-
const alot72 = this.sunriseOffset(-72, false);
|
|
2638
|
-
const tzeit72 = this.sunsetOffset(72, false);
|
|
2639
|
-
const temporalHour = (tzeit72 - alot72) / 12; // ms in hour
|
|
2640
|
-
return new Date(alot72.getTime() + 3 * temporalHour);
|
|
2641
|
-
}
|
|
2642
|
-
/**
|
|
2643
|
-
* Latest Shacharit (MGA); Sunrise plus 4 halachic hours, according to Magen Avraham
|
|
3632
|
+
* Upper edge of the Sun appears over the eastern horizon in the morning (0.833° above horizon)
|
|
2644
3633
|
* @return {Date}
|
|
2645
3634
|
*/
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
const tzeit72 = this.sunsetOffset(72, false);
|
|
2650
|
-
const temporalHour = (tzeit72 - alot72) / 12; // ms in hour
|
|
2651
|
-
return new Date(alot72.getTime() + 4 * temporalHour);
|
|
3635
|
+
seaLevelSunrise() {
|
|
3636
|
+
const zdt = this.noaa.getSeaLevelSunrise();
|
|
3637
|
+
return zdtToDate(zdt);
|
|
2652
3638
|
}
|
|
2653
3639
|
/**
|
|
2654
|
-
*
|
|
3640
|
+
* When the upper edge of the Sun disappears below the horizon (0.833° below horizon)
|
|
2655
3641
|
* @return {Date}
|
|
2656
3642
|
*/
|
|
2657
|
-
|
|
2658
|
-
|
|
3643
|
+
sunset() {
|
|
3644
|
+
const zdt = this.noaa.getSunset();
|
|
3645
|
+
return zdtToDate(zdt);
|
|
2659
3646
|
}
|
|
2660
3647
|
/**
|
|
2661
|
-
*
|
|
3648
|
+
* When the upper edge of the Sun disappears below the horizon (0.833° below horizon)
|
|
2662
3649
|
* @return {Date}
|
|
2663
3650
|
*/
|
|
2664
|
-
|
|
2665
|
-
|
|
3651
|
+
seaLevelSunset() {
|
|
3652
|
+
const zdt = this.noaa.getSeaLevelSunset();
|
|
3653
|
+
return zdtToDate(zdt);
|
|
2666
3654
|
}
|
|
2667
3655
|
/**
|
|
2668
|
-
*
|
|
3656
|
+
* Civil dawn; Sun is 6° below the horizon in the morning
|
|
2669
3657
|
* @return {Date}
|
|
2670
3658
|
*/
|
|
2671
|
-
|
|
2672
|
-
|
|
3659
|
+
dawn() {
|
|
3660
|
+
const zdt = this.noaa.getBeginCivilTwilight();
|
|
3661
|
+
return zdtToDate(zdt);
|
|
2673
3662
|
}
|
|
2674
3663
|
/**
|
|
2675
|
-
*
|
|
2676
|
-
* Default is 8.5 degrees for 3 small stars, use 7.083 degrees for 3 medium-sized stars.
|
|
3664
|
+
* Civil dusk; Sun is 6° below the horizon in the evening
|
|
2677
3665
|
* @return {Date}
|
|
2678
3666
|
*/
|
|
2679
|
-
|
|
2680
|
-
|
|
3667
|
+
dusk() {
|
|
3668
|
+
const zdt = this.noaa.getEndCivilTwilight();
|
|
3669
|
+
return zdtToDate(zdt);
|
|
3670
|
+
}
|
|
3671
|
+
/** @return {Date} */
|
|
3672
|
+
gregEve() {
|
|
3673
|
+
const prev = new Date(this.date);
|
|
3674
|
+
prev.setDate(prev.getDate() - 1);
|
|
3675
|
+
const zman = new Zmanim(this.gloc, prev);
|
|
3676
|
+
return zman.sunset();
|
|
2681
3677
|
}
|
|
2682
3678
|
/**
|
|
2683
|
-
*
|
|
2684
|
-
* @return {
|
|
3679
|
+
* @private
|
|
3680
|
+
* @return {number}
|
|
2685
3681
|
*/
|
|
2686
|
-
|
|
2687
|
-
return this.sunrise();
|
|
3682
|
+
nightHour() {
|
|
3683
|
+
return (this.sunrise() - this.gregEve()) / 12; // ms in hour
|
|
2688
3684
|
}
|
|
2689
3685
|
/**
|
|
2690
|
-
*
|
|
3686
|
+
* Midday – Chatzot; Sunrise plus 6 halachic hours
|
|
2691
3687
|
* @return {Date}
|
|
2692
3688
|
*/
|
|
2693
|
-
|
|
2694
|
-
|
|
3689
|
+
chatzot() {
|
|
3690
|
+
const zdt = this.noaa.getSunTransit();
|
|
3691
|
+
return zdtToDate(zdt);
|
|
2695
3692
|
}
|
|
2696
|
-
|
|
2697
3693
|
/**
|
|
2698
|
-
*
|
|
2699
|
-
* @
|
|
2700
|
-
* @param {Intl.DateTimeFormat} timeFormat
|
|
2701
|
-
* @return {string}
|
|
3694
|
+
* Midnight – Chatzot; Sunset plus 6 halachic hours
|
|
3695
|
+
* @return {Date}
|
|
2702
3696
|
*/
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
const hm = time.split(':');
|
|
2706
|
-
if (hm[0] === '24') {
|
|
2707
|
-
return '00:' + hm[1];
|
|
2708
|
-
}
|
|
2709
|
-
return time;
|
|
3697
|
+
chatzotNight() {
|
|
3698
|
+
return new Date(this.sunrise().getTime() - this.nightHour() * 6);
|
|
2710
3699
|
}
|
|
2711
|
-
|
|
2712
3700
|
/**
|
|
2713
|
-
*
|
|
2714
|
-
* @param {Date} dt
|
|
3701
|
+
* Dawn – Alot haShachar; Sun is 16.1° below the horizon in the morning
|
|
2715
3702
|
* @return {Date}
|
|
2716
3703
|
*/
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
if (isNaN(millis)) {
|
|
2720
|
-
return dt;
|
|
2721
|
-
}
|
|
2722
|
-
// Round up to next minute if needed
|
|
2723
|
-
const millisOnly = dt.getMilliseconds();
|
|
2724
|
-
const seconds = dt.getSeconds();
|
|
2725
|
-
if (seconds === 0 && millisOnly === 0) {
|
|
2726
|
-
return dt;
|
|
2727
|
-
}
|
|
2728
|
-
const secAndMillis = seconds * 1000 + millisOnly;
|
|
2729
|
-
const delta = secAndMillis >= 30000 ? 60000 - secAndMillis : -1 * secAndMillis;
|
|
2730
|
-
return new Date(millis + delta);
|
|
3704
|
+
alotHaShachar() {
|
|
3705
|
+
return this.timeAtAngle(16.1, true);
|
|
2731
3706
|
}
|
|
2732
|
-
|
|
2733
3707
|
/**
|
|
2734
|
-
*
|
|
2735
|
-
* @
|
|
2736
|
-
* @param {Date} date
|
|
2737
|
-
* @return {string}
|
|
3708
|
+
* Earliest talis & tefillin – Misheyakir; Sun is 11.5° below the horizon in the morning
|
|
3709
|
+
* @return {Date}
|
|
2738
3710
|
*/
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
const offsetAbs = Math.abs(offset);
|
|
2742
|
-
const hours = Math.floor(offsetAbs / 60);
|
|
2743
|
-
const minutes = offsetAbs % 60;
|
|
2744
|
-
return (offset < 0 ? '+' : '-') + pad2(hours) + ':' + pad2(minutes);
|
|
3711
|
+
misheyakir() {
|
|
3712
|
+
return this.timeAtAngle(11.5, true);
|
|
2745
3713
|
}
|
|
2746
|
-
|
|
2747
3714
|
/**
|
|
2748
|
-
*
|
|
2749
|
-
* @
|
|
2750
|
-
* @param {Date} date
|
|
2751
|
-
* @return {string}
|
|
3715
|
+
* Earliest talis & tefillin – Misheyakir Machmir; Sun is 10.2° below the horizon in the morning
|
|
3716
|
+
* @return {Date}
|
|
2752
3717
|
*/
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
return null;
|
|
2756
|
-
}
|
|
2757
|
-
return getPseudoISO(tzid, date).substring(0, 19) + Zmanim.timeZoneOffset(tzid, date);
|
|
3718
|
+
misheyakirMachmir() {
|
|
3719
|
+
return this.timeAtAngle(10.2, true);
|
|
2758
3720
|
}
|
|
2759
|
-
|
|
2760
3721
|
/**
|
|
2761
|
-
*
|
|
2762
|
-
* @
|
|
2763
|
-
* @param {
|
|
3722
|
+
* Utility method for using elevation-aware sunrise/sunset
|
|
3723
|
+
* @private
|
|
3724
|
+
* @param {number} hours
|
|
2764
3725
|
* @return {Date}
|
|
2765
3726
|
*/
|
|
2766
|
-
|
|
2767
|
-
const
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
if (offset > 0 && sunrise.getSeconds() >= 30) {
|
|
2774
|
-
offset++;
|
|
2775
|
-
}
|
|
2776
|
-
sunrise.setSeconds(0, 0);
|
|
2777
|
-
}
|
|
2778
|
-
return new Date(sunrise.getTime() + offset * 60 * 1000);
|
|
3727
|
+
getShaahZmanisBasedZman(hours) {
|
|
3728
|
+
const startOfDay = this.noaa.getSunrise();
|
|
3729
|
+
const endOfDay = this.noaa.getSunset();
|
|
3730
|
+
const temporalHour = this.noaa.getTemporalHour(startOfDay, endOfDay);
|
|
3731
|
+
const offset = Math.round(temporalHour * hours);
|
|
3732
|
+
const zdt = NOAACalculator.getTimeOffset(startOfDay, offset);
|
|
3733
|
+
return zdtToDate(zdt);
|
|
2779
3734
|
}
|
|
2780
|
-
|
|
2781
3735
|
/**
|
|
2782
|
-
*
|
|
2783
|
-
* @param {number} offset minutes
|
|
2784
|
-
* @param {boolean} roundMinute round time to nearest minute (default true)
|
|
3736
|
+
* Latest Shema (Gra); Sunrise plus 3 halachic hours, according to the Gra
|
|
2785
3737
|
* @return {Date}
|
|
2786
3738
|
*/
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
return sunset;
|
|
2791
|
-
}
|
|
2792
|
-
if (roundMinute) {
|
|
2793
|
-
// For Havdalah only, round up to next minute if needed
|
|
2794
|
-
if (offset > 0 && sunset.getSeconds() >= 30) {
|
|
2795
|
-
offset++;
|
|
2796
|
-
}
|
|
2797
|
-
sunset.setSeconds(0, 0);
|
|
2798
|
-
}
|
|
2799
|
-
return new Date(sunset.getTime() + offset * 60 * 1000);
|
|
3739
|
+
sofZmanShma() {
|
|
3740
|
+
// Gra
|
|
3741
|
+
return this.getShaahZmanisBasedZman(3);
|
|
2800
3742
|
}
|
|
2801
|
-
|
|
2802
3743
|
/**
|
|
2803
|
-
*
|
|
2804
|
-
* @
|
|
2805
|
-
* @param {number} offset
|
|
2806
|
-
* @param {Intl.DateTimeFormat} timeFormat
|
|
2807
|
-
* @return {Object[]}
|
|
3744
|
+
* Latest Shacharit (Gra); Sunrise plus 4 halachic hours, according to the Gra
|
|
3745
|
+
* @return {Date}
|
|
2808
3746
|
*/
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
// `No sunset for ${location} on ${hd}`
|
|
2813
|
-
return [undefined, undefined];
|
|
2814
|
-
}
|
|
2815
|
-
const time = Zmanim.formatTime(dt, timeFormat);
|
|
2816
|
-
return [dt, time];
|
|
3747
|
+
sofZmanTfilla() {
|
|
3748
|
+
// Gra
|
|
3749
|
+
return this.getShaahZmanisBasedZman(4);
|
|
2817
3750
|
}
|
|
2818
|
-
|
|
2819
3751
|
/**
|
|
2820
|
-
*
|
|
2821
|
-
* @
|
|
2822
|
-
* @param {number} angle degrees for solar depression.
|
|
2823
|
-
* Default is 8.5 degrees for 3 small stars, use 7.083 degrees for 3 medium-sized stars.
|
|
2824
|
-
* @param {Intl.DateTimeFormat} timeFormat
|
|
2825
|
-
* @return {Object[]}
|
|
3752
|
+
* Latest Shema (MGA); Sunrise plus 3 halachic hours, according to Magen Avraham
|
|
3753
|
+
* @return {Date}
|
|
2826
3754
|
*/
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
const timeStr = Zmanim.formatTime(time, timeFormat);
|
|
2834
|
-
return [time, timeStr];
|
|
3755
|
+
sofZmanShmaMGA() {
|
|
3756
|
+
// Magen Avraham
|
|
3757
|
+
const alot72 = this.sunriseOffset(-72, false);
|
|
3758
|
+
const tzeit72 = this.sunsetOffset(72, false);
|
|
3759
|
+
const temporalHour = (tzeit72 - alot72) / 12; // ms in hour
|
|
3760
|
+
return new Date(alot72.getTime() + 3 * temporalHour);
|
|
2835
3761
|
}
|
|
2836
|
-
}
|
|
2837
|
-
|
|
2838
|
-
/*
|
|
2839
|
-
Hebcal - A Jewish Calendar Generator
|
|
2840
|
-
Copyright (c) 1994-2020 Danny Sadinoff
|
|
2841
|
-
Portions copyright Eyal Schachter and Michael J. Radwin
|
|
2842
|
-
|
|
2843
|
-
https://github.com/hebcal/hebcal-es6
|
|
2844
|
-
|
|
2845
|
-
This program is free software; you can redistribute it and/or
|
|
2846
|
-
modify it under the terms of the GNU General Public License
|
|
2847
|
-
as published by the Free Software Foundation; either version 2
|
|
2848
|
-
of the License, or (at your option) any later version.
|
|
2849
|
-
|
|
2850
|
-
This program is distributed in the hope that it will be useful,
|
|
2851
|
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
2852
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
2853
|
-
GNU General Public License for more details.
|
|
2854
|
-
|
|
2855
|
-
You should have received a copy of the GNU General Public License
|
|
2856
|
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
2857
|
-
*/
|
|
2858
|
-
|
|
2859
|
-
const classicCities0 = [['Ashdod', 'IL', 31.79213, 34.64966, 'Asia/Jerusalem'], ['Atlanta', 'US', 33.749, -84.38798, 'America/New_York'], ['Austin', 'US', 30.26715, -97.74306, 'America/Chicago'], ['Baghdad', 'IQ', 33.34058, 44.40088, 'Asia/Baghdad'], ['Beer Sheva', 'IL', 31.25181, 34.7913, 'Asia/Jerusalem'], ['Berlin', 'DE', 52.52437, 13.41053, 'Europe/Berlin'], ['Baltimore', 'US', 39.29038, -76.61219, 'America/New_York'], ['Bogota', 'CO', 4.60971, -74.08175, 'America/Bogota'], ['Boston', 'US', 42.35843, -71.05977, 'America/New_York'], ['Budapest', 'HU', 47.49801, 19.03991, 'Europe/Budapest'], ['Buenos Aires', 'AR', -34.61315, -58.37723, 'America/Argentina/Buenos_Aires'], ['Buffalo', 'US', 42.88645, -78.87837, 'America/New_York'], ['Chicago', 'US', 41.85003, -87.65005, 'America/Chicago'], ['Cincinnati', 'US', 39.162, -84.45689, 'America/New_York'], ['Cleveland', 'US', 41.4995, -81.69541, 'America/New_York'], ['Dallas', 'US', 32.78306, -96.80667, 'America/Chicago'], ['Denver', 'US', 39.73915, -104.9847, 'America/Denver'], ['Detroit', 'US', 42.33143, -83.04575, 'America/Detroit'], ['Eilat', 'IL', 29.55805, 34.94821, 'Asia/Jerusalem'], ['Gibraltar', 'GI', 36.14474, -5.35257, 'Europe/Gibraltar'], ['Haifa', 'IL', 32.81841, 34.9885, 'Asia/Jerusalem'], ['Hawaii', 'US', 21.30694, -157.85833, 'Pacific/Honolulu'], ['Helsinki', 'FI', 60.16952, 24.93545, 'Europe/Helsinki'], ['Houston', 'US', 29.76328, -95.36327, 'America/Chicago'], ['Jerusalem', 'IL', 31.76904, 35.21633, 'Asia/Jerusalem'], ['Johannesburg', 'ZA', -26.20227, 28.04363, 'Africa/Johannesburg'], ['Kiev', 'UA', 50.45466, 30.5238, 'Europe/Kiev'], ['La Paz', 'BO', -16.5, -68.15, 'America/La_Paz'], ['Livingston', 'US', 40.79593, -74.31487, 'America/New_York'], ['Las Vegas', 'US', 36.17497, -115.13722, 'America/Los_Angeles'], ['London', 'GB', 51.50853, -0.12574, 'Europe/London'], ['Los Angeles', 'US', 34.05223, -118.24368, 'America/Los_Angeles'], ['Marseilles', 'FR', 43.29695, 5.38107, 'Europe/Paris'], ['Miami', 'US', 25.77427, -80.19366, 'America/New_York'], ['Minneapolis', 'US', 44.97997, -93.26384, 'America/Chicago'], ['Melbourne', 'AU', -37.814, 144.96332, 'Australia/Melbourne'], ['Mexico City', 'MX', 19.42847, -99.12766, 'America/Mexico_City'], ['Montreal', 'CA', 45.50884, -73.58781, 'America/Toronto'], ['Moscow', 'RU', 55.75222, 37.61556, 'Europe/Moscow'], ['New York', 'US', 40.71427, -74.00597, 'America/New_York'], ['Omaha', 'US', 41.25861, -95.93779, 'America/Chicago'], ['Ottawa', 'CA', 45.41117, -75.69812, 'America/Toronto'], ['Panama City', 'PA', 8.9936, -79.51973, 'America/Panama'], ['Paris', 'FR', 48.85341, 2.3488, 'Europe/Paris'], ['Pawtucket', 'US', 41.87871, -71.38256, 'America/New_York'], ['Petach Tikvah', 'IL', 32.08707, 34.88747, 'Asia/Jerusalem'], ['Philadelphia', 'US', 39.95233, -75.16379, 'America/New_York'], ['Phoenix', 'US', 33.44838, -112.07404, 'America/Phoenix'], ['Pittsburgh', 'US', 40.44062, -79.99589, 'America/New_York'], ['Providence', 'US', 41.82399, -71.41283, 'America/New_York'], ['Portland', 'US', 45.52345, -122.67621, 'America/Los_Angeles'], ['Saint Louis', 'US', 38.62727, -90.19789, 'America/Chicago'], ['Saint Petersburg', 'RU', 59.93863, 30.31413, 'Europe/Moscow'], ['San Diego', 'US', 32.71533, -117.15726, 'America/Los_Angeles'], ['San Francisco', 'US', 37.77493, -122.41942, 'America/Los_Angeles'], ['Sao Paulo', 'BR', -23.5475, -46.63611, 'America/Sao_Paulo'], ['Seattle', 'US', 47.60621, -122.33207, 'America/Los_Angeles'], ['Sydney', 'AU', -33.86785, 151.20732, 'Australia/Sydney'], ['Tel Aviv', 'IL', 32.08088, 34.78057, 'Asia/Jerusalem'], ['Tiberias', 'IL', 32.79221, 35.53124, 'Asia/Jerusalem'], ['Toronto', 'CA', 43.70011, -79.4163, 'America/Toronto'], ['Vancouver', 'CA', 49.24966, -123.11934, 'America/Vancouver'], ['White Plains', 'US', 41.03399, -73.76291, 'America/New_York'], ['Washington DC', 'US', 38.89511, -77.03637, 'America/New_York'], ['Worcester', 'US', 42.26259, -71.80229, 'America/New_York']];
|
|
2860
|
-
const classicCities = Object.create(null);
|
|
2861
|
-
|
|
2862
|
-
// Zip-Codes.com TimeZone IDs
|
|
2863
|
-
const ZIPCODES_TZ_MAP = {
|
|
2864
|
-
'0': 'UTC',
|
|
2865
|
-
'4': 'America/Puerto_Rico',
|
|
2866
|
-
// Atlantic (GMT -04:00)
|
|
2867
|
-
'5': 'America/New_York',
|
|
2868
|
-
// Eastern (GMT -05:00)
|
|
2869
|
-
'6': 'America/Chicago',
|
|
2870
|
-
// Central (GMT -06:00)
|
|
2871
|
-
'7': 'America/Denver',
|
|
2872
|
-
// Mountain (GMT -07:00)
|
|
2873
|
-
'8': 'America/Los_Angeles',
|
|
2874
|
-
// Pacific (GMT -08:00)
|
|
2875
|
-
'9': 'America/Anchorage',
|
|
2876
|
-
// Alaska (GMT -09:00)
|
|
2877
|
-
'10': 'Pacific/Honolulu',
|
|
2878
|
-
// Hawaii-Aleutian Islands (GMT -10:00)
|
|
2879
|
-
'11': 'Pacific/Pago_Pago',
|
|
2880
|
-
// American Samoa (GMT -11:00)
|
|
2881
|
-
'13': 'Pacific/Funafuti',
|
|
2882
|
-
// Marshall Islands (GMT +12:00)
|
|
2883
|
-
'14': 'Pacific/Guam',
|
|
2884
|
-
// Guam (GMT +10:00)
|
|
2885
|
-
'15': 'Pacific/Palau',
|
|
2886
|
-
// Palau (GMT +9:00)
|
|
2887
|
-
'16': 'Pacific/Chuuk' // Micronesia (GMT +11:00)
|
|
2888
|
-
};
|
|
2889
|
-
|
|
2890
|
-
/** @private */
|
|
2891
|
-
const timeFormatCache = Object.create(null);
|
|
2892
|
-
|
|
2893
|
-
/**
|
|
2894
|
-
* Gets a 24-hour time formatter (e.g. 07:41 or 20:03) from cache
|
|
2895
|
-
* or makes a new one if needed
|
|
2896
|
-
* @private
|
|
2897
|
-
* @param {string} tzid
|
|
2898
|
-
* @return {Intl.DateTimeFormat}
|
|
2899
|
-
*/
|
|
2900
|
-
function getFormatter(tzid) {
|
|
2901
|
-
const fmt = timeFormatCache[tzid];
|
|
2902
|
-
if (fmt) return fmt;
|
|
2903
|
-
const f = new Intl.DateTimeFormat('en-US', {
|
|
2904
|
-
timeZone: tzid,
|
|
2905
|
-
hour: 'numeric',
|
|
2906
|
-
minute: 'numeric',
|
|
2907
|
-
hour12: false
|
|
2908
|
-
});
|
|
2909
|
-
timeFormatCache[tzid] = f;
|
|
2910
|
-
return f;
|
|
2911
|
-
}
|
|
2912
|
-
|
|
2913
|
-
/** Class representing Location */
|
|
2914
|
-
class Location {
|
|
2915
3762
|
/**
|
|
2916
|
-
*
|
|
2917
|
-
* @
|
|
2918
|
-
* @param {number} longitude - Longitude as a decimal, valid range -180 thru +180 (e.g. -87.65005)
|
|
2919
|
-
* @param {boolean} il - in Israel (true) or Diaspora (false)
|
|
2920
|
-
* @param {string} tzid - Olson timezone ID, e.g. "America/Chicago"
|
|
2921
|
-
* @param {string} cityName - optional descriptive city name
|
|
2922
|
-
* @param {string} countryCode - ISO 3166 alpha-2 country code (e.g. "FR")
|
|
2923
|
-
* @param {string} geoid - optional string or numeric geographic ID
|
|
3763
|
+
* Latest Shacharit (MGA); Sunrise plus 4 halachic hours, according to Magen Avraham
|
|
3764
|
+
* @return {Date}
|
|
2924
3765
|
*/
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
if (isNaN(long) || long < -180 || long > 180) {
|
|
2932
|
-
throw new RangeError(`Longitude ${longitude} out of range [-180,180]`);
|
|
2933
|
-
}
|
|
2934
|
-
this.latitude = lat;
|
|
2935
|
-
this.longitude = long;
|
|
2936
|
-
this.il = Boolean(il);
|
|
2937
|
-
this.tzid = tzid;
|
|
2938
|
-
this.name = cityName;
|
|
2939
|
-
this.cc = countryCode;
|
|
2940
|
-
this.geoid = geoid;
|
|
2941
|
-
}
|
|
2942
|
-
|
|
2943
|
-
/** @return {number} */
|
|
2944
|
-
getLatitude() {
|
|
2945
|
-
return this.latitude;
|
|
2946
|
-
}
|
|
2947
|
-
|
|
2948
|
-
/** @return {number} */
|
|
2949
|
-
getLongitude() {
|
|
2950
|
-
return this.longitude;
|
|
2951
|
-
}
|
|
2952
|
-
|
|
2953
|
-
/** @return {boolean} */
|
|
2954
|
-
getIsrael() {
|
|
2955
|
-
return this.il;
|
|
2956
|
-
}
|
|
2957
|
-
|
|
2958
|
-
/** @return {string} */
|
|
2959
|
-
getName() {
|
|
2960
|
-
return this.name;
|
|
3766
|
+
sofZmanTfillaMGA() {
|
|
3767
|
+
// Magen Avraham
|
|
3768
|
+
const alot72 = this.sunriseOffset(-72, false);
|
|
3769
|
+
const tzeit72 = this.sunsetOffset(72, false);
|
|
3770
|
+
const temporalHour = (tzeit72 - alot72) / 12; // ms in hour
|
|
3771
|
+
return new Date(alot72.getTime() + 4 * temporalHour);
|
|
2961
3772
|
}
|
|
2962
|
-
|
|
2963
3773
|
/**
|
|
2964
|
-
*
|
|
2965
|
-
* @return {
|
|
3774
|
+
* Earliest Mincha – Mincha Gedola; Sunrise plus 6.5 halachic hours
|
|
3775
|
+
* @return {Date}
|
|
2966
3776
|
*/
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
if (!name) return name;
|
|
2970
|
-
const comma = name.indexOf(', ');
|
|
2971
|
-
if (comma === -1) return name;
|
|
2972
|
-
if (this.cc === 'US' && name[comma + 2] === 'D') {
|
|
2973
|
-
if (name[comma + 3] === 'C') {
|
|
2974
|
-
return name.substring(0, comma + 4);
|
|
2975
|
-
} else if (name[comma + 3] === '.' && name[comma + 4] === 'C') {
|
|
2976
|
-
return name.substring(0, comma + 6);
|
|
2977
|
-
}
|
|
2978
|
-
}
|
|
2979
|
-
return name.substring(0, comma);
|
|
2980
|
-
}
|
|
2981
|
-
|
|
2982
|
-
/** @return {string} */
|
|
2983
|
-
getCountryCode() {
|
|
2984
|
-
return this.cc;
|
|
3777
|
+
minchaGedola() {
|
|
3778
|
+
return this.getShaahZmanisBasedZman(6.5);
|
|
2985
3779
|
}
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
3780
|
+
/**
|
|
3781
|
+
* Preferable earliest time to recite Minchah – Mincha Ketana; Sunrise plus 9.5 halachic hours
|
|
3782
|
+
* @return {Date}
|
|
3783
|
+
*/
|
|
3784
|
+
minchaKetana() {
|
|
3785
|
+
return this.getShaahZmanisBasedZman(9.5);
|
|
2990
3786
|
}
|
|
2991
|
-
|
|
2992
3787
|
/**
|
|
2993
|
-
*
|
|
2994
|
-
* @return {
|
|
3788
|
+
* Plag haMincha; Sunrise plus 10.75 halachic hours
|
|
3789
|
+
* @return {Date}
|
|
2995
3790
|
*/
|
|
2996
|
-
|
|
2997
|
-
return
|
|
3791
|
+
plagHaMincha() {
|
|
3792
|
+
return this.getShaahZmanisBasedZman(10.75);
|
|
2998
3793
|
}
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3794
|
+
/**
|
|
3795
|
+
* @param {number} [angle=8.5] optional time for solar depression.
|
|
3796
|
+
* Default is 8.5 degrees for 3 small stars, use 7.083 degrees for 3 medium-sized stars.
|
|
3797
|
+
* @return {Date}
|
|
3798
|
+
*/
|
|
3799
|
+
tzeit(angle = 8.5) {
|
|
3800
|
+
return this.timeAtAngle(angle, false);
|
|
3003
3801
|
}
|
|
3004
|
-
|
|
3005
3802
|
/**
|
|
3006
|
-
*
|
|
3007
|
-
*
|
|
3008
|
-
* 'Ashdod', 'Atlanta', 'Austin', 'Baghdad', 'Beer Sheva',
|
|
3009
|
-
* 'Berlin', 'Baltimore', 'Bogota', 'Boston', 'Budapest',
|
|
3010
|
-
* 'Buenos Aires', 'Buffalo', 'Chicago', 'Cincinnati', 'Cleveland',
|
|
3011
|
-
* 'Dallas', 'Denver', 'Detroit', 'Eilat', 'Gibraltar', 'Haifa',
|
|
3012
|
-
* 'Hawaii', 'Helsinki', 'Houston', 'Jerusalem', 'Johannesburg',
|
|
3013
|
-
* 'Kiev', 'La Paz', 'Livingston', 'Las Vegas', 'London', 'Los Angeles',
|
|
3014
|
-
* 'Marseilles', 'Miami', 'Minneapolis', 'Melbourne', 'Mexico City',
|
|
3015
|
-
* 'Montreal', 'Moscow', 'New York', 'Omaha', 'Ottawa', 'Panama City',
|
|
3016
|
-
* 'Paris', 'Pawtucket', 'Petach Tikvah', 'Philadelphia', 'Phoenix',
|
|
3017
|
-
* 'Pittsburgh', 'Providence', 'Portland', 'Saint Louis', 'Saint Petersburg',
|
|
3018
|
-
* 'San Diego', 'San Francisco', 'Sao Paulo', 'Seattle', 'Sydney',
|
|
3019
|
-
* 'Tel Aviv', 'Tiberias', 'Toronto', 'Vancouver', 'White Plains',
|
|
3020
|
-
* 'Washington DC', 'Worcester'
|
|
3021
|
-
* @param {string} name
|
|
3022
|
-
* @return {Location}
|
|
3803
|
+
* Alias for sunrise
|
|
3804
|
+
* @return {Date}
|
|
3023
3805
|
*/
|
|
3024
|
-
|
|
3025
|
-
return
|
|
3806
|
+
neitzHaChama() {
|
|
3807
|
+
return this.sunrise();
|
|
3026
3808
|
}
|
|
3027
|
-
|
|
3028
3809
|
/**
|
|
3029
|
-
*
|
|
3030
|
-
* @param {Date|HDate} hdate
|
|
3810
|
+
* Alias for sunset
|
|
3031
3811
|
* @return {Date}
|
|
3032
3812
|
*/
|
|
3033
|
-
|
|
3034
|
-
return
|
|
3813
|
+
shkiah() {
|
|
3814
|
+
return this.sunset();
|
|
3035
3815
|
}
|
|
3036
3816
|
|
|
3037
3817
|
/**
|
|
3038
|
-
*
|
|
3039
|
-
* @param {Date
|
|
3040
|
-
* @param {
|
|
3041
|
-
* @return {
|
|
3818
|
+
* Uses timeFormat to return a date like '20:34'
|
|
3819
|
+
* @param {Date} dt
|
|
3820
|
+
* @param {Intl.DateTimeFormat} timeFormat
|
|
3821
|
+
* @return {string}
|
|
3042
3822
|
*/
|
|
3043
|
-
|
|
3044
|
-
|
|
3823
|
+
static formatTime(dt, timeFormat) {
|
|
3824
|
+
const time = timeFormat.format(dt);
|
|
3825
|
+
const hm = time.split(':');
|
|
3826
|
+
if (hm[0] === '24') {
|
|
3827
|
+
return '00:' + hm[1];
|
|
3828
|
+
}
|
|
3829
|
+
return time;
|
|
3045
3830
|
}
|
|
3046
3831
|
|
|
3047
|
-
/**
|
|
3048
|
-
|
|
3049
|
-
|
|
3832
|
+
/**
|
|
3833
|
+
* Discards seconds, rounding to nearest minute.
|
|
3834
|
+
* @param {Date} dt
|
|
3835
|
+
* @return {Date}
|
|
3836
|
+
*/
|
|
3837
|
+
static roundTime(dt) {
|
|
3838
|
+
const millis = dt.getTime();
|
|
3839
|
+
if (isNaN(millis)) {
|
|
3840
|
+
return dt;
|
|
3841
|
+
}
|
|
3842
|
+
// Round up to next minute if needed
|
|
3843
|
+
const millisOnly = dt.getMilliseconds();
|
|
3844
|
+
const seconds = dt.getSeconds();
|
|
3845
|
+
if (seconds === 0 && millisOnly === 0) {
|
|
3846
|
+
return dt;
|
|
3847
|
+
}
|
|
3848
|
+
const secAndMillis = seconds * 1000 + millisOnly;
|
|
3849
|
+
const delta = secAndMillis >= 30000 ? 60000 - secAndMillis : -1 * secAndMillis;
|
|
3850
|
+
return new Date(millis + delta);
|
|
3050
3851
|
}
|
|
3051
3852
|
|
|
3052
3853
|
/**
|
|
3053
|
-
*
|
|
3054
|
-
* @param {
|
|
3055
|
-
* @param {
|
|
3854
|
+
* Get offset string (like "+05:00" or "-08:00") from tzid (like "Europe/Moscow")
|
|
3855
|
+
* @param {string} tzid
|
|
3856
|
+
* @param {Date} date
|
|
3056
3857
|
* @return {string}
|
|
3057
3858
|
*/
|
|
3058
|
-
static
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
const plus = tz > 0 ? '+' : '';
|
|
3065
|
-
return `Etc/GMT${plus}${tz}`;
|
|
3066
|
-
}
|
|
3067
|
-
} else if (tz == 2 && dst == 'israel') {
|
|
3068
|
-
return 'Asia/Jerusalem';
|
|
3069
|
-
} else if (dst == 'eu') {
|
|
3070
|
-
switch (tz) {
|
|
3071
|
-
case -2:
|
|
3072
|
-
return 'Atlantic/Cape_Verde';
|
|
3073
|
-
case -1:
|
|
3074
|
-
return 'Atlantic/Azores';
|
|
3075
|
-
case 0:
|
|
3076
|
-
return 'Europe/London';
|
|
3077
|
-
case 1:
|
|
3078
|
-
return 'Europe/Paris';
|
|
3079
|
-
case 2:
|
|
3080
|
-
return 'Europe/Athens';
|
|
3081
|
-
}
|
|
3082
|
-
} else if (dst == 'usa') {
|
|
3083
|
-
return ZIPCODES_TZ_MAP[String(tz * -1)];
|
|
3084
|
-
}
|
|
3085
|
-
return undefined;
|
|
3859
|
+
static timeZoneOffset(tzid, date) {
|
|
3860
|
+
const offset = getTimezoneOffset(tzid, date);
|
|
3861
|
+
const offsetAbs = Math.abs(offset);
|
|
3862
|
+
const hours = Math.floor(offsetAbs / 60);
|
|
3863
|
+
const minutes = offsetAbs % 60;
|
|
3864
|
+
return (offset < 0 ? '+' : '-') + pad2(hours) + ':' + pad2(minutes);
|
|
3086
3865
|
}
|
|
3087
3866
|
|
|
3088
3867
|
/**
|
|
3089
|
-
*
|
|
3090
|
-
* @
|
|
3091
|
-
*
|
|
3092
|
-
* @param {string} state two-letter all-caps US state abbreviation like 'CA'
|
|
3093
|
-
* @param {number} tz positive number, 5=America/New_York, 8=America/Los_Angeles
|
|
3094
|
-
* @param {string} dst single char 'Y' or 'N'
|
|
3868
|
+
* Returns a string like "2022-04-01T13:06:00-11:00"
|
|
3869
|
+
* @param {string} tzid
|
|
3870
|
+
* @param {Date} date
|
|
3095
3871
|
* @return {string}
|
|
3096
3872
|
*/
|
|
3097
|
-
static
|
|
3098
|
-
if (
|
|
3099
|
-
return
|
|
3100
|
-
} else if (tz == 7 && state == 'AZ') {
|
|
3101
|
-
return dst == 'Y' ? 'America/Denver' : 'America/Phoenix';
|
|
3102
|
-
} else {
|
|
3103
|
-
return ZIPCODES_TZ_MAP[tz];
|
|
3873
|
+
static formatISOWithTimeZone(tzid, date) {
|
|
3874
|
+
if (isNaN(date.getTime())) {
|
|
3875
|
+
return null;
|
|
3104
3876
|
}
|
|
3877
|
+
return getPseudoISO(tzid, date).substring(0, 19) + Zmanim.timeZoneOffset(tzid, date);
|
|
3105
3878
|
}
|
|
3106
3879
|
|
|
3107
3880
|
/**
|
|
3108
|
-
*
|
|
3109
|
-
* @
|
|
3110
|
-
* @param {
|
|
3111
|
-
* @
|
|
3112
|
-
* @param {string} countryName full country name, e.g. 'Israel' or 'United States'
|
|
3113
|
-
* @return {string}
|
|
3881
|
+
* Returns sunrise + `offset` minutes (either positive or negative).
|
|
3882
|
+
* @param {number} offset minutes
|
|
3883
|
+
* @param {boolean} roundMinute round time to nearest minute (default true)
|
|
3884
|
+
* @return {Date}
|
|
3114
3885
|
*/
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
if (
|
|
3118
|
-
|
|
3119
|
-
if (countryName != 'Israel' && admin1 && admin1.indexOf(cityName) != 0) {
|
|
3120
|
-
cityDescr += ', ' + admin1;
|
|
3886
|
+
sunriseOffset(offset, roundMinute = true) {
|
|
3887
|
+
const sunrise = this.seaLevelSunrise();
|
|
3888
|
+
if (isNaN(sunrise.getTime())) {
|
|
3889
|
+
return sunrise;
|
|
3121
3890
|
}
|
|
3122
|
-
if (
|
|
3123
|
-
|
|
3891
|
+
if (roundMinute) {
|
|
3892
|
+
// For positive offsets only, round up to next minute if needed
|
|
3893
|
+
if (offset > 0 && sunrise.getSeconds() >= 30) {
|
|
3894
|
+
offset++;
|
|
3895
|
+
}
|
|
3896
|
+
sunrise.setSeconds(0, 0);
|
|
3124
3897
|
}
|
|
3125
|
-
return
|
|
3898
|
+
return new Date(sunrise.getTime() + offset * 60 * 1000);
|
|
3126
3899
|
}
|
|
3127
3900
|
|
|
3128
3901
|
/**
|
|
3129
|
-
*
|
|
3130
|
-
*
|
|
3131
|
-
*
|
|
3132
|
-
* @
|
|
3133
|
-
* @param {Location} location
|
|
3134
|
-
* @return {boolean}
|
|
3902
|
+
* Returns sunset + `offset` minutes (either positive or negative).
|
|
3903
|
+
* @param {number} offset minutes
|
|
3904
|
+
* @param {boolean} roundMinute round time to nearest minute (default true)
|
|
3905
|
+
* @return {Date}
|
|
3135
3906
|
*/
|
|
3136
|
-
|
|
3137
|
-
const
|
|
3138
|
-
if (
|
|
3139
|
-
return
|
|
3907
|
+
sunsetOffset(offset, roundMinute = true) {
|
|
3908
|
+
const sunset = this.seaLevelSunset();
|
|
3909
|
+
if (isNaN(sunset.getTime())) {
|
|
3910
|
+
return sunset;
|
|
3140
3911
|
}
|
|
3141
|
-
|
|
3142
|
-
|
|
3912
|
+
if (roundMinute) {
|
|
3913
|
+
// For Havdalah only, round up to next minute if needed
|
|
3914
|
+
if (offset > 0 && sunset.getSeconds() >= 30) {
|
|
3915
|
+
offset++;
|
|
3916
|
+
}
|
|
3917
|
+
sunset.setSeconds(0, 0);
|
|
3918
|
+
}
|
|
3919
|
+
return new Date(sunset.getTime() + offset * 60 * 1000);
|
|
3143
3920
|
}
|
|
3144
3921
|
}
|
|
3145
|
-
classicCities0.forEach(city => {
|
|
3146
|
-
const location = new Location(city[2], city[3], city[1] == 'IL', city[4], city[0], city[1]);
|
|
3147
|
-
Location.addLocation(location.getName(), location);
|
|
3148
|
-
});
|
|
3149
3922
|
|
|
3150
3923
|
/* eslint-disable max-len */
|
|
3151
3924
|
const days = {
|
|
@@ -3182,7 +3955,7 @@ function makeCandleEvent(e, hd, dow, location, options) {
|
|
|
3182
3955
|
}
|
|
3183
3956
|
// if offset is 0 or undefined, we'll use tzeit time
|
|
3184
3957
|
const offset = useHavdalahOffset ? options.havdalahMins : options.candleLightingMins;
|
|
3185
|
-
const zmanim = new Zmanim(
|
|
3958
|
+
const zmanim = new Zmanim(location, hd);
|
|
3186
3959
|
const time = offset ? zmanim.sunsetOffset(offset, true) : zmanim.tzeit(options.havdalahDeg);
|
|
3187
3960
|
if (isNaN(time.getTime())) {
|
|
3188
3961
|
return null; // no sunset
|
|
@@ -3325,7 +4098,7 @@ function makeFastStartEnd(ev, options) {
|
|
|
3325
4098
|
const dt = hd.greg();
|
|
3326
4099
|
const location = options.location;
|
|
3327
4100
|
const fastEndDeg = options.fastEndDeg;
|
|
3328
|
-
const zmanim = new Zmanim(
|
|
4101
|
+
const zmanim = new Zmanim(location, dt);
|
|
3329
4102
|
if (desc === 'Erev Tish\'a B\'Av') {
|
|
3330
4103
|
const sunset = zmanim.sunset();
|
|
3331
4104
|
ev.startEvent = makeTimedEvent(hd, sunset, 'Fast begins', ev, location);
|
|
@@ -3366,7 +4139,7 @@ function makeTimedEvent(hd, time, desc, ev, location) {
|
|
|
3366
4139
|
* @return {TimedEvent}
|
|
3367
4140
|
*/
|
|
3368
4141
|
function makeWeekdayChanukahCandleLighting(ev, hd, location) {
|
|
3369
|
-
const zmanim = new Zmanim(
|
|
4142
|
+
const zmanim = new Zmanim(location, hd.greg());
|
|
3370
4143
|
const candleLightingTime = zmanim.dusk();
|
|
3371
4144
|
// const candleLightingTime = zmanim.tzeit(4.6667);
|
|
3372
4145
|
return makeTimedEvent(hd, candleLightingTime, ev.getDesc(), ev, location);
|
|
@@ -3824,7 +4597,7 @@ class Sedra {
|
|
|
3824
4597
|
|
|
3825
4598
|
return new HDate(this.firstSaturday + idx * 7);
|
|
3826
4599
|
} else if (typeof parsha === 'string') {
|
|
3827
|
-
const num = parsha2id
|
|
4600
|
+
const num = parsha2id.get(parsha);
|
|
3828
4601
|
if (typeof num === 'number') {
|
|
3829
4602
|
return this.find(num);
|
|
3830
4603
|
} else if (parsha.indexOf('-') !== -1) {
|
|
@@ -3843,8 +4616,8 @@ class Sedra {
|
|
|
3843
4616
|
} else if (Array.isArray(parsha) && parsha.length === 2 && typeof parsha[0] === 'string' && typeof parsha[1] === 'string') {
|
|
3844
4617
|
const p1 = parsha[0];
|
|
3845
4618
|
const p2 = parsha[1];
|
|
3846
|
-
const num1 = parsha2id
|
|
3847
|
-
const num2 = parsha2id
|
|
4619
|
+
const num1 = parsha2id.get(p1);
|
|
4620
|
+
const num2 = parsha2id.get(p2);
|
|
3848
4621
|
if (num2 === num1 + 1) {
|
|
3849
4622
|
return this.find(-num1);
|
|
3850
4623
|
} else {
|
|
@@ -3923,10 +4696,10 @@ class Sedra {
|
|
|
3923
4696
|
* @type {string[]}
|
|
3924
4697
|
*/
|
|
3925
4698
|
const parshiot = ['Bereshit', 'Noach', 'Lech-Lecha', 'Vayera', 'Chayei Sara', 'Toldot', 'Vayetzei', 'Vayishlach', 'Vayeshev', 'Miketz', 'Vayigash', 'Vayechi', 'Shemot', 'Vaera', 'Bo', 'Beshalach', 'Yitro', 'Mishpatim', 'Terumah', 'Tetzaveh', 'Ki Tisa', 'Vayakhel', 'Pekudei', 'Vayikra', 'Tzav', 'Shmini', 'Tazria', 'Metzora', 'Achrei Mot', 'Kedoshim', 'Emor', 'Behar', 'Bechukotai', 'Bamidbar', 'Nasso', 'Beha\'alotcha', 'Sh\'lach', 'Korach', 'Chukat', 'Balak', 'Pinchas', 'Matot', 'Masei', 'Devarim', 'Vaetchanan', 'Eikev', 'Re\'eh', 'Shoftim', 'Ki Teitzei', 'Ki Tavo', 'Nitzavim', 'Vayeilech', 'Ha\'azinu'];
|
|
3926
|
-
const parsha2id =
|
|
4699
|
+
const parsha2id = new Map();
|
|
3927
4700
|
for (let id = 0; id < parshiot.length; id++) {
|
|
3928
4701
|
const name = parshiot[id];
|
|
3929
|
-
parsha2id
|
|
4702
|
+
parsha2id.set(name, id);
|
|
3930
4703
|
}
|
|
3931
4704
|
|
|
3932
4705
|
/**
|
|
@@ -4144,7 +4917,7 @@ const SUN$1 = 0;
|
|
|
4144
4917
|
const TUE$1 = 2;
|
|
4145
4918
|
const FRI$2 = 5;
|
|
4146
4919
|
const SAT$2 = 6;
|
|
4147
|
-
const NISAN$
|
|
4920
|
+
const NISAN$2 = months.NISAN;
|
|
4148
4921
|
const IYYAR = months.IYYAR;
|
|
4149
4922
|
|
|
4150
4923
|
/**
|
|
@@ -4162,11 +4935,11 @@ function dateYomHaShoah(year) {
|
|
|
4162
4935
|
if (year < 5711) {
|
|
4163
4936
|
return null;
|
|
4164
4937
|
}
|
|
4165
|
-
let nisan27dt = new HDate(27, NISAN$
|
|
4938
|
+
let nisan27dt = new HDate(27, NISAN$2, year);
|
|
4166
4939
|
if (nisan27dt.getDay() === FRI$2) {
|
|
4167
|
-
nisan27dt = new HDate(26, NISAN$
|
|
4940
|
+
nisan27dt = new HDate(26, NISAN$2, year);
|
|
4168
4941
|
} else if (nisan27dt.getDay() === SUN$1) {
|
|
4169
|
-
nisan27dt = new HDate(28, NISAN$
|
|
4942
|
+
nisan27dt = new HDate(28, NISAN$2, year);
|
|
4170
4943
|
}
|
|
4171
4944
|
return nisan27dt;
|
|
4172
4945
|
}
|
|
@@ -4182,7 +4955,7 @@ function dateYomHaZikaron(year) {
|
|
|
4182
4955
|
return null;
|
|
4183
4956
|
}
|
|
4184
4957
|
let day;
|
|
4185
|
-
const pesach = new HDate(15, NISAN$
|
|
4958
|
+
const pesach = new HDate(15, NISAN$2, year);
|
|
4186
4959
|
const pdow = pesach.getDay();
|
|
4187
4960
|
if (pdow === SUN$1) {
|
|
4188
4961
|
day = 2;
|
|
@@ -4833,7 +5606,7 @@ const TUE = 2;
|
|
|
4833
5606
|
const THU = 4;
|
|
4834
5607
|
const FRI$1 = 5;
|
|
4835
5608
|
const SAT$1 = 6;
|
|
4836
|
-
const NISAN$
|
|
5609
|
+
const NISAN$1 = months.NISAN;
|
|
4837
5610
|
// const IYYAR = months.IYYAR;
|
|
4838
5611
|
// const SIVAN = months.SIVAN;
|
|
4839
5612
|
const TAMUZ = months.TAMUZ;
|
|
@@ -4841,10 +5614,10 @@ const AV = months.AV;
|
|
|
4841
5614
|
const ELUL$1 = months.ELUL;
|
|
4842
5615
|
const TISHREI$1 = months.TISHREI;
|
|
4843
5616
|
// const CHESHVAN = months.CHESHVAN;
|
|
4844
|
-
const KISLEV
|
|
4845
|
-
const TEVET
|
|
5617
|
+
const KISLEV = months.KISLEV;
|
|
5618
|
+
const TEVET = months.TEVET;
|
|
4846
5619
|
// const SHVAT = months.SHVAT;
|
|
4847
|
-
const ADAR_I
|
|
5620
|
+
const ADAR_I = months.ADAR_I;
|
|
4848
5621
|
// const ADAR_II = months.ADAR_II;
|
|
4849
5622
|
|
|
4850
5623
|
const CHAG = flags.CHAG;
|
|
@@ -4916,7 +5689,7 @@ const emojiIsraelFlag = {
|
|
|
4916
5689
|
emoji: '🇮🇱'
|
|
4917
5690
|
};
|
|
4918
5691
|
const chanukahEmoji = '🕎';
|
|
4919
|
-
const yearCache =
|
|
5692
|
+
const yearCache = new Map();
|
|
4920
5693
|
const KEYCAP_DIGITS = ['0️⃣', '1️⃣', '2️⃣', '3️⃣', '4️⃣', '5️⃣', '6️⃣', '7️⃣', '8️⃣', '9️⃣'];
|
|
4921
5694
|
|
|
4922
5695
|
/**
|
|
@@ -4933,12 +5706,12 @@ function getHolidaysForYear_(year) {
|
|
|
4933
5706
|
} else if (year < 1 || year > 32658) {
|
|
4934
5707
|
throw new RangeError(`Hebrew year ${year} out of range 1-32658`);
|
|
4935
5708
|
}
|
|
4936
|
-
const cached = yearCache
|
|
5709
|
+
const cached = yearCache.get(year);
|
|
4937
5710
|
if (cached) {
|
|
4938
5711
|
return cached;
|
|
4939
5712
|
}
|
|
4940
5713
|
const RH = new HDate(1, TISHREI$1, year);
|
|
4941
|
-
const pesach = new HDate(15, NISAN$
|
|
5714
|
+
const pesach = new HDate(15, NISAN$1, year);
|
|
4942
5715
|
const h = new SimpleMap();
|
|
4943
5716
|
// eslint-disable-next-line require-jsdoc
|
|
4944
5717
|
function add(...events) {
|
|
@@ -4972,27 +5745,27 @@ function getHolidaysForYear_(year) {
|
|
|
4972
5745
|
add(new HolidayEvent(new HDate(3 + (RH.getDay() == THU), TISHREI$1, year), 'Tzom Gedaliah', MINOR_FAST$1));
|
|
4973
5746
|
// first SAT after RH
|
|
4974
5747
|
add(new HolidayEvent(new HDate(HDate.dayOnOrBefore(SAT$1, 7 + RH.abs())), 'Shabbat Shuva', SPECIAL_SHABBAT$1));
|
|
4975
|
-
const rchTevet = HDate.shortKislev(year) ? new HDate(1, TEVET
|
|
5748
|
+
const rchTevet = HDate.shortKislev(year) ? new HDate(1, TEVET, year) : new HDate(30, KISLEV, year);
|
|
4976
5749
|
add(new HolidayEvent(rchTevet, 'Chag HaBanot', MINOR_HOLIDAY$1));
|
|
4977
5750
|
// yes, we know Kislev 30-32 are wrong
|
|
4978
5751
|
// HDate() corrects the month automatically
|
|
4979
5752
|
for (let candles = 2; candles <= 8; candles++) {
|
|
4980
|
-
const hd = new HDate(23 + candles, KISLEV
|
|
5753
|
+
const hd = new HDate(23 + candles, KISLEV, year);
|
|
4981
5754
|
add(new HolidayEvent(hd, `Chanukah: ${candles} Candles`, MINOR_HOLIDAY$1 | CHANUKAH_CANDLES$1, {
|
|
4982
5755
|
chanukahDay: candles - 1,
|
|
4983
5756
|
emoji: chanukahEmoji + KEYCAP_DIGITS[candles]
|
|
4984
5757
|
}));
|
|
4985
5758
|
}
|
|
4986
|
-
add(new HolidayEvent(new HDate(32, KISLEV
|
|
5759
|
+
add(new HolidayEvent(new HDate(32, KISLEV, year), 'Chanukah: 8th Day', MINOR_HOLIDAY$1, {
|
|
4987
5760
|
chanukahDay: 8,
|
|
4988
5761
|
emoji: chanukahEmoji
|
|
4989
5762
|
}));
|
|
4990
|
-
add(new AsaraBTevetEvent(new HDate(10, TEVET
|
|
5763
|
+
add(new AsaraBTevetEvent(new HDate(10, TEVET, year), 'Asara B\'Tevet', MINOR_FAST$1));
|
|
4991
5764
|
const pesachAbs = pesach.abs();
|
|
4992
5765
|
add(new HolidayEvent(new HDate(HDate.dayOnOrBefore(SAT$1, pesachAbs - 43)), 'Shabbat Shekalim', SPECIAL_SHABBAT$1), new HolidayEvent(new HDate(HDate.dayOnOrBefore(SAT$1, pesachAbs - 30)), 'Shabbat Zachor', SPECIAL_SHABBAT$1), new HolidayEvent(new HDate(pesachAbs - (pesach.getDay() == TUE ? 33 : 31)), 'Ta\'anit Esther', MINOR_FAST$1));
|
|
4993
5766
|
add(new HolidayEvent(new HDate(HDate.dayOnOrBefore(SAT$1, pesachAbs - 14) - 7), 'Shabbat Parah', SPECIAL_SHABBAT$1), new HolidayEvent(new HDate(HDate.dayOnOrBefore(SAT$1, pesachAbs - 14)), 'Shabbat HaChodesh', SPECIAL_SHABBAT$1), new HolidayEvent(new HDate(HDate.dayOnOrBefore(SAT$1, pesachAbs - 1)), 'Shabbat HaGadol', SPECIAL_SHABBAT$1), new HolidayEvent(
|
|
4994
5767
|
// if the fast falls on Shabbat, move to Thursday
|
|
4995
|
-
pesach.prev().getDay() == SAT$1 ? pesach.onOrBefore(THU) : new HDate(14, NISAN$
|
|
5768
|
+
pesach.prev().getDay() == SAT$1 ? pesach.onOrBefore(THU) : new HDate(14, NISAN$1, year), 'Ta\'anit Bechorot', MINOR_FAST$1));
|
|
4996
5769
|
add(new HolidayEvent(new HDate(HDate.dayOnOrBefore(SAT$1, new HDate(1, TISHREI$1, year + 1).abs() - 4)), 'Leil Selichot', MINOR_HOLIDAY$1, {
|
|
4997
5770
|
emoji: '🕍'
|
|
4998
5771
|
}));
|
|
@@ -5000,10 +5773,10 @@ function getHolidaysForYear_(year) {
|
|
|
5000
5773
|
add(new HolidayEvent(new HDate(16, months.ADAR_II, year), 'Purim Meshulash', MINOR_HOLIDAY$1));
|
|
5001
5774
|
}
|
|
5002
5775
|
if (HDate.isLeapYear(year)) {
|
|
5003
|
-
add(new HolidayEvent(new HDate(14, ADAR_I
|
|
5776
|
+
add(new HolidayEvent(new HDate(14, ADAR_I, year), 'Purim Katan', MINOR_HOLIDAY$1, {
|
|
5004
5777
|
emoji: '🎭️'
|
|
5005
5778
|
}));
|
|
5006
|
-
add(new HolidayEvent(new HDate(15, ADAR_I
|
|
5779
|
+
add(new HolidayEvent(new HDate(15, ADAR_I, year), 'Shushan Purim Katan', MINOR_HOLIDAY$1, {
|
|
5007
5780
|
emoji: '🎭️'
|
|
5008
5781
|
}));
|
|
5009
5782
|
}
|
|
@@ -5058,7 +5831,7 @@ function getHolidaysForYear_(year) {
|
|
|
5058
5831
|
const monthsInYear = HDate.monthsInYear(year);
|
|
5059
5832
|
for (let month = 1; month <= monthsInYear; month++) {
|
|
5060
5833
|
const monthName = HDate.getMonthName(month, year);
|
|
5061
|
-
if ((month == NISAN$
|
|
5834
|
+
if ((month == NISAN$1 ? HDate.daysInMonth(HDate.monthsInYear(year - 1), year - 1) : HDate.daysInMonth(month - 1, year)) == 30) {
|
|
5062
5835
|
add(new RoshChodeshEvent(new HDate(1, month, year), monthName));
|
|
5063
5836
|
add(new RoshChodeshEvent(new HDate(30, month - 1, year), monthName));
|
|
5064
5837
|
} else if (month !== TISHREI$1) {
|
|
@@ -5104,7 +5877,7 @@ function getHolidaysForYear_(year) {
|
|
|
5104
5877
|
emoji: '☀️'
|
|
5105
5878
|
}));
|
|
5106
5879
|
}
|
|
5107
|
-
yearCache
|
|
5880
|
+
yearCache.set(year, h);
|
|
5108
5881
|
return h;
|
|
5109
5882
|
}
|
|
5110
5883
|
|
|
@@ -5122,7 +5895,7 @@ function getHolidaysForYear_(year) {
|
|
|
5122
5895
|
*/
|
|
5123
5896
|
function getBirkatHaChama(year) {
|
|
5124
5897
|
const leap = HDate.isLeapYear(year);
|
|
5125
|
-
const startMonth = leap ? months.ADAR_II : NISAN$
|
|
5898
|
+
const startMonth = leap ? months.ADAR_II : NISAN$1;
|
|
5126
5899
|
const startDay = leap ? 20 : 1;
|
|
5127
5900
|
const baseRd = HDate.hebrew2abs(year, startMonth, startDay);
|
|
5128
5901
|
for (let day = 0; day <= 40; day++) {
|
|
@@ -5136,7 +5909,7 @@ function getBirkatHaChama(year) {
|
|
|
5136
5909
|
}
|
|
5137
5910
|
|
|
5138
5911
|
/** @private */
|
|
5139
|
-
const cals =
|
|
5912
|
+
const cals = new Map();
|
|
5140
5913
|
|
|
5141
5914
|
/**
|
|
5142
5915
|
* Plug-ins for daily learning calendars such as Daf Yomi, Mishna Yomi, Nach Yomi, etc.
|
|
@@ -5153,7 +5926,7 @@ class DailyLearning {
|
|
|
5153
5926
|
if (typeof calendar !== 'function') {
|
|
5154
5927
|
throw new TypeError(`Invalid calendar function: ${calendar}`);
|
|
5155
5928
|
}
|
|
5156
|
-
cals
|
|
5929
|
+
cals.set(name, calendar);
|
|
5157
5930
|
}
|
|
5158
5931
|
|
|
5159
5932
|
/**
|
|
@@ -5164,7 +5937,7 @@ class DailyLearning {
|
|
|
5164
5937
|
* @return {Event}
|
|
5165
5938
|
*/
|
|
5166
5939
|
static lookup(name, hd) {
|
|
5167
|
-
const fn = cals
|
|
5940
|
+
const fn = cals.get(name);
|
|
5168
5941
|
if (typeof fn === 'function') {
|
|
5169
5942
|
return fn(hd);
|
|
5170
5943
|
}
|
|
@@ -5172,95 +5945,7 @@ class DailyLearning {
|
|
|
5172
5945
|
}
|
|
5173
5946
|
}
|
|
5174
5947
|
|
|
5175
|
-
const
|
|
5176
|
-
const CHESHVAN = months.CHESHVAN;
|
|
5177
|
-
const KISLEV = months.KISLEV;
|
|
5178
|
-
const TEVET = months.TEVET;
|
|
5179
|
-
const SHVAT = months.SHVAT;
|
|
5180
|
-
const ADAR_I = months.ADAR_I;
|
|
5181
|
-
const ADAR_II = months.ADAR_II;
|
|
5182
|
-
|
|
5183
|
-
/**
|
|
5184
|
-
* @private
|
|
5185
|
-
* @param {number} hyear Hebrew year
|
|
5186
|
-
* @param {Date|HDate} gdate Gregorian or Hebrew date of death
|
|
5187
|
-
* @return {HDate} anniversary occurring in hyear
|
|
5188
|
-
*/
|
|
5189
|
-
function getYahrzeit_(hyear, gdate) {
|
|
5190
|
-
const orig = HDate.isHDate(gdate) ? gdate : new HDate(gdate);
|
|
5191
|
-
let hDeath = {
|
|
5192
|
-
yy: orig.getFullYear(),
|
|
5193
|
-
mm: orig.getMonth(),
|
|
5194
|
-
dd: orig.getDate()
|
|
5195
|
-
};
|
|
5196
|
-
if (hyear <= hDeath.yy) {
|
|
5197
|
-
// `Hebrew year ${hyear} occurs on or before original date in ${hDeath.yy}`
|
|
5198
|
-
return undefined;
|
|
5199
|
-
}
|
|
5200
|
-
if (hDeath.mm == CHESHVAN && hDeath.dd == 30 && !longCheshvan(hDeath.yy + 1)) {
|
|
5201
|
-
// If it's Heshvan 30 it depends on the first anniversary;
|
|
5202
|
-
// if that was not Heshvan 30, use the day before Kislev 1.
|
|
5203
|
-
hDeath = abs2hebrew(hebrew2abs(hyear, KISLEV, 1) - 1);
|
|
5204
|
-
} else if (hDeath.mm == KISLEV && hDeath.dd == 30 && shortKislev(hDeath.yy + 1)) {
|
|
5205
|
-
// If it's Kislev 30 it depends on the first anniversary;
|
|
5206
|
-
// if that was not Kislev 30, use the day before Teveth 1.
|
|
5207
|
-
hDeath = abs2hebrew(hebrew2abs(hyear, TEVET, 1) - 1);
|
|
5208
|
-
} else if (hDeath.mm == ADAR_II) {
|
|
5209
|
-
// If it's Adar II, use the same day in last month of year (Adar or Adar II).
|
|
5210
|
-
hDeath.mm = monthsInYear(hyear);
|
|
5211
|
-
} else if (hDeath.mm == ADAR_I && hDeath.dd == 30 && !isLeapYear(hyear)) {
|
|
5212
|
-
// If it's the 30th in Adar I and year is not a leap year
|
|
5213
|
-
// (so Adar has only 29 days), use the last day in Shevat.
|
|
5214
|
-
hDeath.dd = 30;
|
|
5215
|
-
hDeath.mm = SHVAT;
|
|
5216
|
-
}
|
|
5217
|
-
// In all other cases, use the normal anniversary of the date of death.
|
|
5218
|
-
|
|
5219
|
-
// advance day to rosh chodesh if needed
|
|
5220
|
-
if (hDeath.mm == CHESHVAN && hDeath.dd == 30 && !longCheshvan(hyear)) {
|
|
5221
|
-
hDeath.mm = KISLEV;
|
|
5222
|
-
hDeath.dd = 1;
|
|
5223
|
-
} else if (hDeath.mm == KISLEV && hDeath.dd == 30 && shortKislev(hyear)) {
|
|
5224
|
-
hDeath.mm = TEVET;
|
|
5225
|
-
hDeath.dd = 1;
|
|
5226
|
-
}
|
|
5227
|
-
return new HDate(hDeath.dd, hDeath.mm, hyear);
|
|
5228
|
-
}
|
|
5229
|
-
|
|
5230
|
-
/**
|
|
5231
|
-
* @private
|
|
5232
|
-
* @param {number} hyear Hebrew year
|
|
5233
|
-
* @param {Date|HDate} gdate Gregorian or Hebrew date of event
|
|
5234
|
-
* @return {HDate} anniversary occurring in `hyear`
|
|
5235
|
-
*/
|
|
5236
|
-
function getBirthdayOrAnniversary_(hyear, gdate) {
|
|
5237
|
-
const orig = HDate.isHDate(gdate) ? gdate : new HDate(gdate);
|
|
5238
|
-
const origYear = orig.getFullYear();
|
|
5239
|
-
if (hyear === origYear) {
|
|
5240
|
-
return orig;
|
|
5241
|
-
} else if (hyear < origYear) {
|
|
5242
|
-
// `Hebrew year ${hyear} occurs on or before original date in ${origYear}`
|
|
5243
|
-
return undefined;
|
|
5244
|
-
}
|
|
5245
|
-
const isOrigLeap = isLeapYear(origYear);
|
|
5246
|
-
let month = orig.getMonth();
|
|
5247
|
-
let day = orig.getDate();
|
|
5248
|
-
if (month == ADAR_I && !isOrigLeap || month == ADAR_II && isOrigLeap) {
|
|
5249
|
-
month = monthsInYear(hyear);
|
|
5250
|
-
} else if (month == CHESHVAN && day == 30 && !longCheshvan(hyear)) {
|
|
5251
|
-
month = KISLEV;
|
|
5252
|
-
day = 1;
|
|
5253
|
-
} else if (month == KISLEV && day == 30 && shortKislev(hyear)) {
|
|
5254
|
-
month = TEVET;
|
|
5255
|
-
day = 1;
|
|
5256
|
-
} else if (month == ADAR_I && day == 30 && isOrigLeap && !isLeapYear(hyear)) {
|
|
5257
|
-
month = NISAN$1;
|
|
5258
|
-
day = 1;
|
|
5259
|
-
}
|
|
5260
|
-
return new HDate(day, month, hyear);
|
|
5261
|
-
}
|
|
5262
|
-
|
|
5263
|
-
const version="4.5.1";
|
|
5948
|
+
const version="5.0.0-rc1";
|
|
5264
5949
|
|
|
5265
5950
|
const headers$1={"plural-forms":"nplurals=2; plural=(n > 1);"};const contexts$1={"":{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"],Tevet:["Teves"],"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"]}};var poAshkenazi = {headers:headers$1,contexts:contexts$1};
|
|
5266
5951
|
|
|
@@ -5337,7 +6022,7 @@ function range(start, end) {
|
|
|
5337
6022
|
}
|
|
5338
6023
|
return arr;
|
|
5339
6024
|
}
|
|
5340
|
-
const cache =
|
|
6025
|
+
const cache = new Map();
|
|
5341
6026
|
const NONE = {
|
|
5342
6027
|
shacharit: false,
|
|
5343
6028
|
mincha: false,
|
|
@@ -5364,7 +6049,11 @@ function tachanun_(hdate, il) {
|
|
|
5364
6049
|
function tachanun0(hdate, il, checkNext) {
|
|
5365
6050
|
const year = hdate.getFullYear();
|
|
5366
6051
|
const key = `${year}-${il ? 1 : 0}`;
|
|
5367
|
-
const
|
|
6052
|
+
const cached = cache.get(key);
|
|
6053
|
+
const dates = cached || tachanunYear(year, il);
|
|
6054
|
+
if (!cached) {
|
|
6055
|
+
cache.set(key, dates);
|
|
6056
|
+
}
|
|
5368
6057
|
const abs = hdate.abs();
|
|
5369
6058
|
if (dates.none.indexOf(abs) > -1) {
|
|
5370
6059
|
return NONE;
|
|
@@ -5512,7 +6201,7 @@ const MINOR_HOLIDAY = flags.MINOR_HOLIDAY;
|
|
|
5512
6201
|
const EREV = flags.EREV;
|
|
5513
6202
|
const CHOL_HAMOED = flags.CHOL_HAMOED;
|
|
5514
6203
|
const YOM_KIPPUR_KATAN = flags.YOM_KIPPUR_KATAN;
|
|
5515
|
-
const unrecognizedAlreadyWarned =
|
|
6204
|
+
const unrecognizedAlreadyWarned = new Set();
|
|
5516
6205
|
const RECOGNIZED_OPTIONS = {
|
|
5517
6206
|
location: 1,
|
|
5518
6207
|
year: 1,
|
|
@@ -5554,9 +6243,9 @@ const RECOGNIZED_OPTIONS = {
|
|
|
5554
6243
|
*/
|
|
5555
6244
|
function warnUnrecognizedOptions(options) {
|
|
5556
6245
|
Object.keys(options).forEach(k => {
|
|
5557
|
-
if (typeof RECOGNIZED_OPTIONS[k] === 'undefined' && !unrecognizedAlreadyWarned
|
|
6246
|
+
if (typeof RECOGNIZED_OPTIONS[k] === 'undefined' && !unrecognizedAlreadyWarned.has(k)) {
|
|
5558
6247
|
console.warn(`Ignoring unrecognized HebrewCalendar option: ${k}`);
|
|
5559
|
-
unrecognizedAlreadyWarned
|
|
6248
|
+
unrecognizedAlreadyWarned.add(k);
|
|
5560
6249
|
}
|
|
5561
6250
|
});
|
|
5562
6251
|
}
|
|
@@ -5721,7 +6410,7 @@ function checkCandleOptions(options) {
|
|
|
5721
6410
|
*/
|
|
5722
6411
|
function getAbs(d) {
|
|
5723
6412
|
if (typeof d == 'number') return d;
|
|
5724
|
-
if (isDate(d)) return greg2abs(d);
|
|
6413
|
+
if (greg.isDate(d)) return greg.greg2abs(d);
|
|
5725
6414
|
if (HDate.isHDate(d)) return d.abs();
|
|
5726
6415
|
throw new TypeError(`Invalid date type: ${d}`);
|
|
5727
6416
|
}
|
|
@@ -5771,17 +6460,17 @@ function getStartAndEnd(options) {
|
|
|
5771
6460
|
if (theYear < 100) {
|
|
5772
6461
|
startGreg.setFullYear(theYear);
|
|
5773
6462
|
}
|
|
5774
|
-
const startAbs = greg2abs(startGreg);
|
|
6463
|
+
const startAbs = greg.greg2abs(startGreg);
|
|
5775
6464
|
let endAbs;
|
|
5776
6465
|
if (options.month) {
|
|
5777
|
-
endAbs = startAbs + daysInMonth
|
|
6466
|
+
endAbs = startAbs + greg.daysInMonth(theMonth, theYear) - 1;
|
|
5778
6467
|
} else {
|
|
5779
6468
|
const endYear = theYear + numYears;
|
|
5780
6469
|
const endGreg = new Date(endYear, 0, 1);
|
|
5781
6470
|
if (endYear < 100) {
|
|
5782
6471
|
endGreg.setFullYear(endYear);
|
|
5783
6472
|
}
|
|
5784
|
-
endAbs = greg2abs(endGreg) - 1;
|
|
6473
|
+
endAbs = greg.greg2abs(endGreg) - 1;
|
|
5785
6474
|
}
|
|
5786
6475
|
return [startAbs, endAbs];
|
|
5787
6476
|
}
|
|
@@ -5925,7 +6614,7 @@ function observedInIsrael(ev) {
|
|
|
5925
6614
|
function observedInDiaspora(ev) {
|
|
5926
6615
|
return ev.observedInDiaspora();
|
|
5927
6616
|
}
|
|
5928
|
-
const yearArrayCache =
|
|
6617
|
+
const yearArrayCache = new Map();
|
|
5929
6618
|
|
|
5930
6619
|
/**
|
|
5931
6620
|
* HebrewCalendar is the main interface to the `@hebcal/core` library.
|
|
@@ -6070,7 +6759,7 @@ class HebrewCalendar {
|
|
|
6070
6759
|
warnUnrecognizedOptions(options);
|
|
6071
6760
|
const startAbs = startAndEnd[0];
|
|
6072
6761
|
const endAbs = startAndEnd[1];
|
|
6073
|
-
const startGreg = abs2greg(startAbs);
|
|
6762
|
+
const startGreg = greg.abs2greg(startAbs);
|
|
6074
6763
|
if (startGreg.getFullYear() < 100) {
|
|
6075
6764
|
options.candlelighting = false;
|
|
6076
6765
|
}
|
|
@@ -6118,7 +6807,7 @@ class HebrewCalendar {
|
|
|
6118
6807
|
const omer = abs - beginOmer + 1;
|
|
6119
6808
|
const omerEv = new OmerEvent(hd, omer);
|
|
6120
6809
|
if (options.candlelighting) {
|
|
6121
|
-
const zmanim = new Zmanim(
|
|
6810
|
+
const zmanim = new Zmanim(location, hd.prev());
|
|
6122
6811
|
const tzeit = zmanim.tzeit(7.0833);
|
|
6123
6812
|
if (!isNaN(tzeit.getTime())) {
|
|
6124
6813
|
omerEv.alarm = tzeit;
|
|
@@ -6183,7 +6872,8 @@ class HebrewCalendar {
|
|
|
6183
6872
|
* @return {HDate} anniversary occurring in `hyear`
|
|
6184
6873
|
*/
|
|
6185
6874
|
static getBirthdayOrAnniversary(hyear, gdate) {
|
|
6186
|
-
|
|
6875
|
+
const dt = getBirthdayOrAnniversary(hyear, gdate);
|
|
6876
|
+
return new HDate(dt);
|
|
6187
6877
|
}
|
|
6188
6878
|
|
|
6189
6879
|
/**
|
|
@@ -6221,7 +6911,8 @@ class HebrewCalendar {
|
|
|
6221
6911
|
* @return {HDate} anniversary occurring in hyear
|
|
6222
6912
|
*/
|
|
6223
6913
|
static getYahrzeit(hyear, gdate) {
|
|
6224
|
-
|
|
6914
|
+
const dt = getYahrzeit(hyear, gdate);
|
|
6915
|
+
return new HDate(dt);
|
|
6225
6916
|
}
|
|
6226
6917
|
|
|
6227
6918
|
/**
|
|
@@ -6244,7 +6935,7 @@ class HebrewCalendar {
|
|
|
6244
6935
|
*/
|
|
6245
6936
|
static getHolidaysForYearArray(year, il) {
|
|
6246
6937
|
const cacheKey = `${year}-${il ? 1 : 0}`;
|
|
6247
|
-
let events = yearArrayCache
|
|
6938
|
+
let events = yearArrayCache.get(cacheKey);
|
|
6248
6939
|
if (events) {
|
|
6249
6940
|
return events;
|
|
6250
6941
|
}
|
|
@@ -6261,7 +6952,7 @@ class HebrewCalendar {
|
|
|
6261
6952
|
events = events.concat(filtered);
|
|
6262
6953
|
}
|
|
6263
6954
|
}
|
|
6264
|
-
yearArrayCache
|
|
6955
|
+
yearArrayCache.set(cacheKey, events);
|
|
6265
6956
|
return events;
|
|
6266
6957
|
}
|
|
6267
6958
|
|
|
@@ -6443,4 +7134,4 @@ function appendHolidayAndRelated(events, ev, options, candlesEv, dow) {
|
|
|
6443
7134
|
return candlesEv;
|
|
6444
7135
|
}
|
|
6445
7136
|
|
|
6446
|
-
export { AsaraBTevetEvent, CandleLightingEvent, DailyLearning, Event, HDate, HavdalahEvent, HebrewCalendar, HebrewDateEvent, HolidayEvent, Locale, Location, MevarchimChodeshEvent, Molad, MoladEvent, OmerEvent, ParshaEvent, RoshChodeshEvent, RoshHashanaEvent, Sedra,
|
|
7137
|
+
export { AsaraBTevetEvent, CandleLightingEvent, DailyLearning, Event, GeoLocation, HDate, HavdalahEvent, HebrewCalendar, HebrewDateEvent, HolidayEvent, Locale, Location, MevarchimChodeshEvent, Molad, MoladEvent, NOAACalculator, OmerEvent, ParshaEvent, RoshChodeshEvent, RoshHashanaEvent, Sedra, TimedEvent, Zmanim, flags, gematriya, gematriyaStrToNum, months, parshiot, version };
|