@hebcal/core 6.0.5 → 6.0.7

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.
Files changed (149) hide show
  1. package/README.md +42 -27
  2. package/dist/bundle.js +26 -15
  3. package/dist/bundle.js.map +1 -1
  4. package/dist/bundle.min.js +3 -3
  5. package/dist/bundle.min.js.map +1 -1
  6. package/dist/esm/DailyLearning.js +1 -1
  7. package/dist/esm/HebrewDateEvent.js +1 -1
  8. package/dist/esm/HolidayEvent.js +2 -2
  9. package/dist/esm/HolidayEvent.js.map +1 -1
  10. package/dist/esm/MevarchimChodeshEvent.js +1 -1
  11. package/dist/esm/ParshaEvent.js +2 -2
  12. package/dist/esm/ParshaEvent.js.map +1 -1
  13. package/dist/esm/TimedEvent.js +1 -1
  14. package/dist/esm/YomKippurKatanEvent.js +1 -1
  15. package/dist/esm/ashkenazi.po.js +1 -1
  16. package/dist/esm/calendar.js +7 -5
  17. package/dist/esm/calendar.js.map +1 -1
  18. package/dist/esm/candles.js +1 -1
  19. package/dist/esm/event.js +1 -1
  20. package/dist/esm/getStartAndEnd.js +1 -1
  21. package/dist/esm/hallel.js +1 -1
  22. package/dist/esm/he-x-NoNikud.po.d.ts +2 -0
  23. package/dist/esm/he-x-NoNikud.po.js +2 -2
  24. package/dist/esm/he-x-NoNikud.po.js.map +1 -1
  25. package/dist/esm/he.po.d.ts +1 -0
  26. package/dist/esm/he.po.js +2 -2
  27. package/dist/esm/he.po.js.map +1 -1
  28. package/dist/esm/hebcal.js +1 -1
  29. package/dist/esm/holidays.js +1 -1
  30. package/dist/esm/holidays.js.map +1 -1
  31. package/dist/esm/index.js +1 -1
  32. package/dist/esm/isAssurBemlacha.js +1 -1
  33. package/dist/esm/locale.js +1 -1
  34. package/dist/esm/location.js +2 -2
  35. package/dist/esm/location.js.map +1 -1
  36. package/dist/esm/modern.js +1 -1
  37. package/dist/esm/molad.js +1 -1
  38. package/dist/esm/omer.d.ts +1 -1
  39. package/dist/esm/omer.js +6 -2
  40. package/dist/esm/omer.js.map +1 -1
  41. package/dist/esm/parshaName.js +1 -1
  42. package/dist/esm/parshaYear.d.ts +2 -2
  43. package/dist/esm/parshaYear.js +1 -1
  44. package/dist/esm/parshaYear.js.map +1 -1
  45. package/dist/esm/pkgVersion.d.ts +1 -1
  46. package/dist/esm/pkgVersion.js +2 -2
  47. package/dist/esm/pkgVersion.js.map +1 -1
  48. package/dist/esm/reformatTimeStr.js +1 -1
  49. package/dist/esm/sedra.d.ts +5 -1
  50. package/dist/esm/sedra.js +9 -3
  51. package/dist/esm/sedra.js.map +1 -1
  52. package/dist/esm/staticHolidays.js +1 -2
  53. package/dist/esm/staticHolidays.js.map +1 -1
  54. package/dist/esm/tachanun.js +1 -1
  55. package/dist/esm/zmanim.js +1 -1
  56. package/dist/he-x-NoNikud.po.d.ts +2 -0
  57. package/dist/he.po.d.ts +1 -0
  58. package/dist/omer.d.ts +1 -1
  59. package/dist/parshaYear.d.ts +2 -2
  60. package/dist/pkgVersion.d.ts +1 -1
  61. package/dist/po2json.d.ts +1 -0
  62. package/dist/po2json.js +41 -0
  63. package/dist/sedra.d.ts +5 -1
  64. package/dist/size-demo/dist/getHoliday.d.ts +1944 -0
  65. package/dist/size-demo/dist/getHoliday.js +3712 -0
  66. package/dist/size-demo/dist/parshiyot.js +10662 -0
  67. package/dist/size-demo/dist/sedra.d.ts +1411 -0
  68. package/dist/size-demo/dist/sedra.js +2359 -0
  69. package/dist/size-demo/dist/tachanun.d.ts +1015 -0
  70. package/dist/size-demo/dist/tachanun.js +1755 -0
  71. package/dist/size-demo/getHoliday.d.ts +1 -0
  72. package/dist/size-demo/getHoliday.js +3 -0
  73. package/dist/size-demo/parshiyot.d.ts +1 -0
  74. package/dist/size-demo/parshiyot.js +11 -0
  75. package/dist/size-demo/rollup.config.d.ts +3 -0
  76. package/dist/size-demo/rollup.config.js +47 -0
  77. package/dist/size-demo/sedra.d.ts +1 -0
  78. package/dist/size-demo/sedra.js +3 -0
  79. package/dist/size-demo/tachanun.d.ts +1 -0
  80. package/dist/size-demo/tachanun.js +3 -0
  81. package/dist/src/CalOptions.d.ts +168 -0
  82. package/dist/src/CalOptions.js +1 -0
  83. package/dist/src/DailyLearning.d.ts +32 -0
  84. package/dist/src/DailyLearning.js +55 -0
  85. package/dist/src/HebrewDateEvent.d.ts +37 -0
  86. package/dist/src/HebrewDateEvent.js +72 -0
  87. package/dist/src/HolidayEvent.d.ts +83 -0
  88. package/dist/src/HolidayEvent.js +186 -0
  89. package/dist/src/MevarchimChodeshEvent.d.ts +26 -0
  90. package/dist/src/MevarchimChodeshEvent.js +50 -0
  91. package/dist/src/ParshaEvent.d.ts +19 -0
  92. package/dist/src/ParshaEvent.js +43 -0
  93. package/dist/src/TimedEvent.d.ts +47 -0
  94. package/dist/src/TimedEvent.js +92 -0
  95. package/dist/src/YomKippurKatanEvent.d.ts +23 -0
  96. package/dist/src/YomKippurKatanEvent.js +38 -0
  97. package/dist/src/ashkenazi.po.d.ts +70 -0
  98. package/dist/src/ashkenazi.po.js +1 -0
  99. package/dist/src/calendar.d.ts +111 -0
  100. package/dist/src/calendar.js +660 -0
  101. package/dist/src/candles.d.ts +44 -0
  102. package/dist/src/candles.js +163 -0
  103. package/dist/src/event.d.ts +188 -0
  104. package/dist/src/event.js +233 -0
  105. package/dist/src/getStartAndEnd.d.ts +6 -0
  106. package/dist/src/getStartAndEnd.js +97 -0
  107. package/dist/src/hallel.d.ts +6 -0
  108. package/dist/src/hallel.js +47 -0
  109. package/dist/src/he-x-NoNikud.po.d.ts +15 -0
  110. package/dist/src/he-x-NoNikud.po.js +1 -0
  111. package/dist/src/he.po.d.ts +195 -0
  112. package/dist/src/he.po.js +1 -0
  113. package/dist/src/hebcal.d.ts +260 -0
  114. package/dist/src/hebcal.js +332 -0
  115. package/dist/src/holidays.d.ts +22 -0
  116. package/dist/src/holidays.js +288 -0
  117. package/dist/src/index.d.ts +26 -0
  118. package/dist/src/index.js +24 -0
  119. package/dist/src/isAssurBemlacha.d.ts +9 -0
  120. package/dist/src/isAssurBemlacha.js +62 -0
  121. package/dist/src/locale.d.ts +2 -0
  122. package/dist/src/locale.js +11 -0
  123. package/dist/src/location.d.ts +73 -0
  124. package/dist/src/location.js +306 -0
  125. package/dist/src/modern.d.ts +18 -0
  126. package/dist/src/modern.js +59 -0
  127. package/dist/src/molad.d.ts +62 -0
  128. package/dist/src/molad.js +169 -0
  129. package/dist/src/omer.d.ts +53 -0
  130. package/dist/src/omer.js +302 -0
  131. package/dist/src/parshaName.d.ts +2 -0
  132. package/dist/src/parshaName.js +13 -0
  133. package/dist/src/parshaYear.d.ts +9 -0
  134. package/dist/src/parshaYear.js +24 -0
  135. package/dist/src/pkgVersion.d.ts +2 -0
  136. package/dist/src/pkgVersion.js +2 -0
  137. package/dist/src/reformatTimeStr.d.ts +8 -0
  138. package/dist/src/reformatTimeStr.js +48 -0
  139. package/dist/src/sedra.d.ts +95 -0
  140. package/dist/src/sedra.js +477 -0
  141. package/dist/src/staticHolidays.d.ts +176 -0
  142. package/dist/src/staticHolidays.js +614 -0
  143. package/dist/src/tachanun.d.ts +29 -0
  144. package/dist/src/tachanun.js +120 -0
  145. package/dist/src/zmanim.d.ts +347 -0
  146. package/dist/src/zmanim.js +579 -0
  147. package/dist/version.d.ts +1 -0
  148. package/dist/version.js +9 -0
  149. package/package.json +12 -9
@@ -0,0 +1,579 @@
1
+ import 'temporal-polyfill/global';
2
+ import { NOAACalculator } from '@hebcal/noaa';
3
+ import { HDate, getPseudoISO, getTimezoneOffset, isDate, pad2, } from '@hebcal/hdate';
4
+ /**
5
+ * @private
6
+ */
7
+ function zdtToDate(zdt) {
8
+ if (zdt === null) {
9
+ return new Date(NaN);
10
+ }
11
+ const res = new Date(zdt.epochMilliseconds);
12
+ res.setMilliseconds(0);
13
+ return res;
14
+ }
15
+ function getDate(date) {
16
+ if (isDate(date))
17
+ return date;
18
+ if (HDate.isHDate(date))
19
+ return date.greg();
20
+ throw new TypeError(`invalid date: ${date}`);
21
+ }
22
+ /**
23
+ * Calculate halachic times (zmanim / זְמַנִּים) for a given day and location.
24
+ * Calculations are available for tzeit / tzais (nightfall),
25
+ * shkiah (sunset) and more.
26
+ *
27
+ * Zmanim are estimated using an algorithm published by the US National Oceanic
28
+ * and Atmospheric Administration. The NOAA solar calculator is based on equations
29
+ * from _Astronomical Algorithms_ by Jean Meeus.
30
+ *
31
+ * The sunrise and sunset results are theoretically accurate to within a minute for
32
+ * locations between +/- 72° latitude, and within 10 minutes outside of those latitudes.
33
+ * However, due to variations in atmospheric composition, temperature, pressure and
34
+ * conditions, observed values may vary from calculations.
35
+ * https://gml.noaa.gov/grad/solcalc/calcdetails.html
36
+ *
37
+ * @example
38
+ * const {GeoLocation, Zmanim} = require('@hebcal/core');
39
+ * const latitude = 41.822232;
40
+ * const longitude = -71.448292;
41
+ * const tzid = 'America/New_York';
42
+ * const friday = new Date(2023, 8, 8);
43
+ * const gloc = new GeoLocation(null, latitude, longitude, 0, tzid);
44
+ * const zmanim = new Zmanim(gloc, friday, false);
45
+ * const candleLighting = zmanim.sunsetOffset(-18, true);
46
+ * const timeStr = Zmanim.formatISOWithTimeZone(tzid, candleLighting);
47
+ */
48
+ export class Zmanim {
49
+ /**
50
+ * Initialize a Zmanim instance.
51
+ * @param gloc GeoLocation including latitude, longitude, and timezone
52
+ * @param date Regular or Hebrew Date. If `date` is a regular `Date`,
53
+ * hours, minutes, seconds and milliseconds are ignored.
54
+ * @param useElevation use elevation for calculations (default `false`).
55
+ * If `true`, use elevation to affect the calculation of all sunrise/sunset based
56
+ * zmanim. Note: there are some zmanim such as degree-based zmanim that are driven
57
+ * by the amount of light in the sky and are not impacted by elevation.
58
+ * These zmanim intentionally do not support elevation adjustment.
59
+ */
60
+ constructor(gloc, date, useElevation) {
61
+ const dt = getDate(date);
62
+ this.date = dt;
63
+ this.gloc = gloc;
64
+ const plainDate = Temporal.PlainDate.from({
65
+ year: dt.getFullYear(),
66
+ month: dt.getMonth() + 1,
67
+ day: dt.getDate(),
68
+ });
69
+ this.noaa = new NOAACalculator(gloc, plainDate);
70
+ this.useElevation = Boolean(useElevation);
71
+ }
72
+ /**
73
+ * Returns `true` if elevation adjustment is enabled
74
+ * for zmanim support elevation adjustment
75
+ */
76
+ getUseElevation() {
77
+ return this.useElevation;
78
+ }
79
+ /**
80
+ * Enables or disables elevation adjustment for zmanim support elevation adjustment
81
+ * @param useElevation
82
+ */
83
+ setUseElevation(useElevation) {
84
+ this.useElevation = useElevation;
85
+ }
86
+ /**
87
+ * Convenience function to get the time when sun is above or below the horizon
88
+ * for a certain angle (in degrees).
89
+ * This function does not support elevation adjustment.
90
+ * @param angle
91
+ * @param rising
92
+ */
93
+ timeAtAngle(angle, rising) {
94
+ const offsetZenith = 90 + angle;
95
+ const zdt = rising
96
+ ? this.noaa.getSunriseOffsetByDegrees(offsetZenith)
97
+ : this.noaa.getSunsetOffsetByDegrees(offsetZenith);
98
+ return zdtToDate(zdt);
99
+ }
100
+ /**
101
+ * Upper edge of the Sun appears over the eastern horizon in the morning (0.833° above horizon)
102
+ * If elevation is enabled, this function will include elevation in the calculation.
103
+ */
104
+ sunrise() {
105
+ const zdt = this.useElevation
106
+ ? this.noaa.getSunrise()
107
+ : this.noaa.getSeaLevelSunrise();
108
+ return zdtToDate(zdt);
109
+ }
110
+ /**
111
+ * Upper edge of the Sun appears over the eastern horizon in the morning (0.833° above horizon).
112
+ * This function does not support elevation adjustment.
113
+ */
114
+ seaLevelSunrise() {
115
+ const zdt = this.noaa.getSeaLevelSunrise();
116
+ return zdtToDate(zdt);
117
+ }
118
+ /**
119
+ * When the upper edge of the Sun disappears below the horizon (0.833° below horizon).
120
+ * If elevation is enabled, this function will include elevation in the calculation.
121
+ */
122
+ sunset() {
123
+ const zdt = this.useElevation
124
+ ? this.noaa.getSunset()
125
+ : this.noaa.getSeaLevelSunset();
126
+ return zdtToDate(zdt);
127
+ }
128
+ /**
129
+ * When the upper edge of the Sun disappears below the horizon (0.833° below horizon).
130
+ * This function does not support elevation adjustment.
131
+ */
132
+ seaLevelSunset() {
133
+ const zdt = this.noaa.getSeaLevelSunset();
134
+ return zdtToDate(zdt);
135
+ }
136
+ /**
137
+ * Civil dawn; Sun is 6° below the horizon in the morning.
138
+ * Because degree-based functions estimate the amount of light in the sky,
139
+ * the result is not impacted by elevation.
140
+ */
141
+ dawn() {
142
+ const zdt = this.noaa.getBeginCivilTwilight();
143
+ return zdtToDate(zdt);
144
+ }
145
+ /**
146
+ * Civil dusk; Sun is 6° below the horizon in the evening.
147
+ * Because degree-based functions estimate the amount of light in the sky,
148
+ * the result is not impacted by elevation.
149
+ */
150
+ dusk() {
151
+ const zdt = this.noaa.getEndCivilTwilight();
152
+ return zdtToDate(zdt);
153
+ }
154
+ /**
155
+ * Returns sunset for the previous day.
156
+ * If elevation is enabled, this function will include elevation in the calculation.
157
+ */
158
+ gregEve() {
159
+ const prev = new Date(this.date);
160
+ prev.setDate(prev.getDate() - 1);
161
+ const zman = new Zmanim(this.gloc, prev, this.useElevation);
162
+ return zman.sunset();
163
+ }
164
+ /**
165
+ * @private
166
+ */
167
+ nightHour() {
168
+ return (this.sunrise().getTime() - this.gregEve().getTime()) / 12; // ms in hour
169
+ }
170
+ /**
171
+ * Midday – Chatzot; Sunrise plus 6 halachic hours
172
+ */
173
+ chatzot() {
174
+ const startOfDay = this.noaa.getSeaLevelSunrise();
175
+ const endOfDay = this.noaa.getSeaLevelSunset();
176
+ const zdt = this.noaa.getSunTransit(startOfDay, endOfDay);
177
+ return zdtToDate(zdt);
178
+ }
179
+ /**
180
+ * Midnight – Chatzot; Sunset plus 6 halachic hours.
181
+ * If elevation is enabled, this function will include elevation in the calculation.
182
+ */
183
+ chatzotNight() {
184
+ return new Date(this.sunrise().getTime() - this.nightHour() * 6);
185
+ }
186
+ /**
187
+ * Dawn – Alot haShachar; Sun is 16.1° below the horizon in the morning.
188
+ * Because degree-based functions estimate the amount of light in the sky,
189
+ * the result is not impacted by elevation.
190
+ */
191
+ alotHaShachar() {
192
+ return this.timeAtAngle(16.1, true);
193
+ }
194
+ /**
195
+ * Dawn – Alot haShachar; calculated as 72 minutes before sunrise or
196
+ * sea level sunrise.
197
+ */
198
+ alotHaShachar72() {
199
+ return this.sunriseOffset(-72, false, false);
200
+ }
201
+ /**
202
+ * Earliest talis & tefillin – Misheyakir; Sun is 11.5° below the horizon in the morning.
203
+ * Because degree-based functions estimate the amount of light in the sky,
204
+ * the result is not impacted by elevation.
205
+ */
206
+ misheyakir() {
207
+ return this.timeAtAngle(11.5, true);
208
+ }
209
+ /**
210
+ * Earliest talis & tefillin – Misheyakir Machmir; Sun is 10.2° below the horizon in the morning.
211
+ * Because degree-based functions estimate the amount of light in the sky,
212
+ * the result is not impacted by elevation.
213
+ */
214
+ misheyakirMachmir() {
215
+ return this.timeAtAngle(10.2, true);
216
+ }
217
+ /**
218
+ * Utility method for using elevation-aware sunrise/sunset
219
+ * @private
220
+ * @param hours
221
+ */
222
+ getShaahZmanisBasedZman(hours) {
223
+ const startOfDay = this.useElevation
224
+ ? this.noaa.getSunrise()
225
+ : this.noaa.getSeaLevelSunrise();
226
+ const endOfDay = this.useElevation
227
+ ? this.noaa.getSunset()
228
+ : this.noaa.getSeaLevelSunset();
229
+ const temporalHour = this.noaa.getTemporalHour(startOfDay, endOfDay);
230
+ const offset = Math.round(temporalHour * hours);
231
+ const zdt = NOAACalculator.getTimeOffset(startOfDay, offset);
232
+ return zdtToDate(zdt);
233
+ }
234
+ /**
235
+ * Latest Shema (Gra); Sunrise plus 3 halachic hours, according to the Gra.
236
+ * If elevation is enabled, this function will include elevation in the calculation.
237
+ */
238
+ sofZmanShma() {
239
+ // Gra
240
+ return this.getShaahZmanisBasedZman(3);
241
+ }
242
+ /**
243
+ * Latest Shacharit (Gra); Sunrise plus 4 halachic hours, according to the Gra.
244
+ *
245
+ * This method returns the latest *zman tfila* (time to recite shema in the morning)
246
+ * that is 4 *shaos zmaniyos* (solar hours) after sunrise or sea level sunrise
247
+ * (depending on the `useElevation` setting), according
248
+ * to the [GRA](https://en.wikipedia.org/wiki/Vilna_Gaon).
249
+ *
250
+ * If elevation is enabled, this function will include elevation in the calculation.
251
+ */
252
+ sofZmanTfilla() {
253
+ // Gra
254
+ return this.getShaahZmanisBasedZman(4);
255
+ }
256
+ /**
257
+ * Returns an array with alot (Date) and ms in hour (number)
258
+ * @private
259
+ */
260
+ getTemporalHour72(forceSeaLevel) {
261
+ const alot72 = this.sunriseOffset(-72, false, forceSeaLevel);
262
+ const tzeit72 = this.sunsetOffset(72, false, forceSeaLevel);
263
+ const temporalHour = (tzeit72.getTime() - alot72.getTime()) / 12;
264
+ return [alot72, temporalHour];
265
+ }
266
+ /**
267
+ * Returns an array with alot (Date) and ms in hour (number)
268
+ * @private
269
+ */
270
+ getTemporalHourByDeg(angle) {
271
+ const alot = this.timeAtAngle(angle, true);
272
+ const tzeit = this.timeAtAngle(angle, false);
273
+ const temporalHour = (tzeit.getTime() - alot.getTime()) / 12;
274
+ return [alot, temporalHour];
275
+ }
276
+ /**
277
+ * Latest Shema (MGA); Sunrise plus 3 halachic hours, according to Magen Avraham.
278
+ * Based on the opinion of the MGA that the day is calculated from
279
+ * dawn being fixed 72 minutes before sea-level sunrise, and nightfall is fixed
280
+ * 72 minutes after sea-level sunset.
281
+ */
282
+ sofZmanShmaMGA() {
283
+ // Magen Avraham
284
+ const [alot72, temporalHour] = this.getTemporalHour72(true);
285
+ const offset = Math.floor(3 * temporalHour);
286
+ return new Date(alot72.getTime() + offset);
287
+ }
288
+ /**
289
+ * Latest Shema (MGA); Sunrise plus 3 halachic hours, according to Magen Avraham.
290
+ * Based on the opinion of the MGA that the day is calculated from
291
+ * dawn to nightfall with both being 16.1° below the horizon.
292
+ */
293
+ sofZmanShmaMGA16Point1() {
294
+ const [alot, temporalHour] = this.getTemporalHourByDeg(16.1);
295
+ const offset = Math.floor(3 * temporalHour);
296
+ return new Date(alot.getTime() + offset);
297
+ }
298
+ /**
299
+ * Latest Shema (MGA); Sunrise plus 3 halachic hours, according to Magen Avraham.
300
+ * Based on the opinion of the MGA that the day is calculated from
301
+ * dawn to nightfall with both being 19.8° below the horizon.
302
+ *
303
+ * This calculation is based on the position of the sun 90 minutes after sunset in Jerusalem
304
+ * around the equinox / equilux which calculates to 19.8° below geometric zenith.
305
+ * https://kosherjava.com/2022/01/12/equinox-vs-equilux-zmanim-calculations/
306
+ */
307
+ sofZmanShmaMGA19Point8() {
308
+ const [alot, temporalHour] = this.getTemporalHourByDeg(19.8);
309
+ const offset = Math.floor(3 * temporalHour);
310
+ return new Date(alot.getTime() + offset);
311
+ }
312
+ /**
313
+ * Latest Shacharit (MGA); Sunrise plus 4 halachic hours, according to Magen Avraham
314
+ */
315
+ sofZmanTfillaMGA() {
316
+ // Magen Avraham
317
+ const [alot72, temporalHour] = this.getTemporalHour72(true);
318
+ const offset = Math.floor(4 * temporalHour);
319
+ return new Date(alot72.getTime() + offset);
320
+ }
321
+ /**
322
+ * Latest Shacharit (MGA); Sunrise plus 4 halachic hours, according to Magen Avraham.
323
+ * Based on the opinion of the MGA that the day is calculated from
324
+ * dawn to nightfall with both being 16.1° below the horizon.
325
+ */
326
+ sofZmanTfillaMGA16Point1() {
327
+ const [alot, temporalHour] = this.getTemporalHourByDeg(16.1);
328
+ const offset = Math.floor(4 * temporalHour);
329
+ return new Date(alot.getTime() + offset);
330
+ }
331
+ /**
332
+ * Latest Shacharit (MGA); Sunrise plus 4 halachic hours, according to Magen Avraham.
333
+ * Based on the opinion of the MGA that the day is calculated from
334
+ * dawn to nightfall with both being 19.8° below the horizon.
335
+ *
336
+ * This calculation is based on the position of the sun 90 minutes after sunset in Jerusalem
337
+ * around the equinox / equilux which calculates to 19.8° below geometric zenith.
338
+ * https://kosherjava.com/2022/01/12/equinox-vs-equilux-zmanim-calculations/
339
+ */
340
+ sofZmanTfillaMGA19Point8() {
341
+ const [alot, temporalHour] = this.getTemporalHourByDeg(19.8);
342
+ const offset = Math.floor(4 * temporalHour);
343
+ return new Date(alot.getTime() + offset);
344
+ }
345
+ /**
346
+ * Earliest Mincha – Mincha Gedola (GRA); Sunrise plus 6.5 halachic hours.
347
+ * If elevation is enabled, this function will include elevation in the calculation.
348
+ *
349
+ * This method returns the latest mincha gedola, the earliest time one can pray mincha
350
+ * that is 6.5 shaos zmaniyos (solar hours) after sunrise or sea level sunrise
351
+ * (depending on the `useElevation` setting), according
352
+ * to the [GRA](https://en.wikipedia.org/wiki/Vilna_Gaon).
353
+ *
354
+ * The Ramba"m is of the opinion that it is better to delay *mincha* until
355
+ * *mincha ketana* while the Ra"sh, Tur, GRA and others are of the
356
+ * opinion that *mincha* can be prayed *lechatchila* starting at *mincha gedola*.
357
+ */
358
+ minchaGedola() {
359
+ return this.getShaahZmanisBasedZman(6.5);
360
+ }
361
+ /**
362
+ * Earliest Mincha – Mincha Gedola (MGA); Sunrise plus 6.5 halachic hours.
363
+ * If elevation is enabled, this function will include elevation in the calculation.
364
+ *
365
+ * This method returns the time of *mincha gedola* according to the Magen Avraham
366
+ * with the day starting 72 minutes before sunrise and ending 72 minutes after sunset.
367
+ * This is the earliest time to pray *mincha*.
368
+ */
369
+ minchaGedolaMGA() {
370
+ const [alot72, temporalHour] = this.getTemporalHour72(false);
371
+ const offset = Math.floor(6.5 * temporalHour);
372
+ return new Date(alot72.getTime() + offset);
373
+ }
374
+ /**
375
+ * Preferable earliest time to recite Minchah – Mincha Ketana; Sunrise plus 9.5 halachic hours.
376
+ * If elevation is enabled, this function will include elevation in the calculation.
377
+ *
378
+ * This method returns *mincha ketana*, the preferred earliest time to pray *mincha* in the
379
+ * opinion of the [Rambam](https://en.wikipedia.org/wiki/Maimonides) and others,
380
+ * that is 9.5 *shaos zmaniyos* (solar hours) after sunrise or sea level sunrise
381
+ * (depending on the `useElevation` setting), according
382
+ * to the [GRA](https://en.wikipedia.org/wiki/Vilna_Gaon).
383
+ */
384
+ minchaKetana() {
385
+ return this.getShaahZmanisBasedZman(9.5);
386
+ }
387
+ /**
388
+ * This method returns the time of *mincha ketana* according to the Magen Avraham
389
+ * with the day starting 72 minutes before sunrise and ending 72 minutes after sunset.
390
+ * This is the preferred earliest time to pray *mincha* according to the opinion of
391
+ * the [Rambam](https://en.wikipedia.org/wiki/Maimonides) and others.
392
+ *
393
+ * If elevation is enabled, this function will include elevation in the calculation.
394
+ */
395
+ minchaKetanaMGA() {
396
+ const [alot72, temporalHour] = this.getTemporalHour72(false);
397
+ return new Date(alot72.getTime() + Math.floor(9.5 * temporalHour));
398
+ }
399
+ /**
400
+ * Plag haMincha; Sunrise plus 10.75 halachic hours.
401
+ * If elevation is enabled, this function will include elevation in the calculation.
402
+ */
403
+ plagHaMincha() {
404
+ return this.getShaahZmanisBasedZman(10.75);
405
+ }
406
+ /**
407
+ * @param [angle=8.5] optional time for solar depression.
408
+ * Default is 8.5 degrees for 3 small stars, use 7.083 degrees for 3 medium-sized stars.
409
+ * Because degree-based functions estimate the amount of light in the sky,
410
+ * the result is not impacted by elevation.
411
+ */
412
+ tzeit(angle = 8.5) {
413
+ return this.timeAtAngle(angle, false);
414
+ }
415
+ /**
416
+ * Alias for sunrise
417
+ */
418
+ neitzHaChama() {
419
+ return this.sunrise();
420
+ }
421
+ /**
422
+ * Alias for sunset
423
+ */
424
+ shkiah() {
425
+ return this.sunset();
426
+ }
427
+ /**
428
+ * Rabbeinu Tam holds that bein hashmashos is a specific time
429
+ * between sunset and tzeis hakochavim.
430
+ * One opinion on how to calculate this time is that
431
+ * it is 13.5 minutes before tzies 7.083.
432
+ * Because degree-based functions estimate the amount of light in the sky,
433
+ * the result is not impacted by elevation.
434
+ */
435
+ beinHaShmashos() {
436
+ const tzeit = this.tzeit(7.083);
437
+ const millis = tzeit.getTime();
438
+ if (isNaN(millis)) {
439
+ return tzeit;
440
+ }
441
+ return new Date(millis - 13.5 * 60 * 1000);
442
+ }
443
+ /**
444
+ * Uses timeFormat to return a date like '20:34'.
445
+ * Returns `XX:XX` if the date is invalid.
446
+ */
447
+ static formatTime(dt, timeFormat) {
448
+ if (isNaN(dt.getTime())) {
449
+ return 'XX:XX'; // Invalid Date
450
+ }
451
+ const time = timeFormat.format(dt);
452
+ const hm = time.split(':');
453
+ if (hm[0] === '24') {
454
+ return '00:' + hm[1];
455
+ }
456
+ return time;
457
+ }
458
+ /**
459
+ * Discards seconds, rounding to nearest minute.
460
+ * @param dt
461
+ */
462
+ static roundTime(dt) {
463
+ const millis = dt.getTime();
464
+ if (isNaN(millis)) {
465
+ return dt;
466
+ }
467
+ // Round up to next minute if needed
468
+ const millisOnly = dt.getMilliseconds();
469
+ const seconds = dt.getSeconds();
470
+ if (seconds === 0 && millisOnly === 0) {
471
+ return dt;
472
+ }
473
+ const secAndMillis = seconds * 1000 + millisOnly;
474
+ const delta = secAndMillis >= 30000 ? 60000 - secAndMillis : -1 * secAndMillis;
475
+ return new Date(millis + delta);
476
+ }
477
+ /**
478
+ * Get offset string (like "+05:00" or "-08:00") from tzid (like "Europe/Moscow")
479
+ * @param tzid
480
+ * @param date
481
+ */
482
+ static timeZoneOffset(tzid, date) {
483
+ const offset = getTimezoneOffset(tzid, date);
484
+ const offsetAbs = Math.abs(offset);
485
+ const hours = Math.floor(offsetAbs / 60);
486
+ const minutes = offsetAbs % 60;
487
+ return (offset < 0 ? '+' : '-') + pad2(hours) + ':' + pad2(minutes);
488
+ }
489
+ /**
490
+ * Returns a string like "2022-04-01T13:06:00-11:00"
491
+ * @param tzid
492
+ * @param date
493
+ */
494
+ static formatISOWithTimeZone(tzid, date) {
495
+ if (isNaN(date.getTime())) {
496
+ return '0000-00-00T00:00:00Z';
497
+ }
498
+ return (getPseudoISO(tzid, date).substring(0, 19) +
499
+ Zmanim.timeZoneOffset(tzid, date));
500
+ }
501
+ /**
502
+ * Returns sunrise + `offset` minutes (either positive or negative).
503
+ * If elevation is enabled, this function will include elevation in the calculation
504
+ * unless `forceSeaLevel` is `true`.
505
+ * @param offset minutes
506
+ * @param roundMinute round time to nearest minute (default true)
507
+ * @param forceSeaLevel use sea-level sunrise (default false)
508
+ */
509
+ sunriseOffset(offset, roundMinute = true, forceSeaLevel = false) {
510
+ const sunrise = forceSeaLevel ? this.seaLevelSunrise() : this.sunrise();
511
+ if (isNaN(sunrise.getTime())) {
512
+ return sunrise;
513
+ }
514
+ if (roundMinute) {
515
+ // For positive offsets only, round up to next minute if needed
516
+ if (offset > 0 && sunrise.getSeconds() >= 30) {
517
+ offset++;
518
+ }
519
+ sunrise.setSeconds(0, 0);
520
+ }
521
+ return new Date(sunrise.getTime() + offset * 60 * 1000);
522
+ }
523
+ /**
524
+ * Returns sunset + `offset` minutes (either positive or negative).
525
+ * If elevation is enabled, this function will include elevation in the calculation
526
+ * unless `forceSeaLevel` is `true`.
527
+ * @param offset minutes
528
+ * @param roundMinute round time to nearest minute (default true)
529
+ * @param forceSeaLevel use sea-level sunset (default false)
530
+ */
531
+ sunsetOffset(offset, roundMinute = true, forceSeaLevel = false) {
532
+ const sunset = forceSeaLevel ? this.seaLevelSunset() : this.sunset();
533
+ if (isNaN(sunset.getTime())) {
534
+ return sunset;
535
+ }
536
+ if (roundMinute) {
537
+ // For Havdalah only, round up to next minute if needed
538
+ if (offset > 0 && sunset.getSeconds() >= 30) {
539
+ offset++;
540
+ }
541
+ sunset.setSeconds(0, 0);
542
+ }
543
+ return new Date(sunset.getTime() + offset * 60 * 1000);
544
+ }
545
+ /**
546
+ * Returns the Hebrew date relative to the specified location and Gregorian date,
547
+ * taking into consideration whether the time is before or after sunset.
548
+ *
549
+ * For example, if the given date and is `2024-09-22T10:35` (before sunset), and
550
+ * sunset for the specified location is **19:04**, then this function would
551
+ * return a Hebrew date of `19th of Elul, 5784`.
552
+ * If the given date is the same Gregorian day after sunset
553
+ * (for example `2024-09-22T20:07`), this function would return a
554
+ * Hebrew date of `20th of Elul, 5784`.
555
+ * @example
556
+ * const {GeoLocation, Zmanim, HDate} = require('@hebcal/core');
557
+ * const latitude = 48.85341;
558
+ * const longitude = 2.3488;
559
+ * const timezone = 'Europe/Paris';
560
+ * const gloc = new GeoLocation(null, latitude, longitude, 0, timezone);
561
+ * const before = Zmanim.makeSunsetAwareHDate(gloc, new Date('2024-09-22T17:38:46.123Z'), false);
562
+ * console.log(before.toString()); // '19 Elul 5784'
563
+ * const after = Zmanim.makeSunsetAwareHDate(gloc, new Date('2024-09-22T23:45:18.345Z'), false);
564
+ * console.log(after.toString()); // '20 Elul 5784'
565
+ */
566
+ static makeSunsetAwareHDate(gloc, date, useElevation) {
567
+ const zmanim = new Zmanim(gloc, date, useElevation);
568
+ const sunset = zmanim.sunset();
569
+ let hd = new HDate(date);
570
+ const sunsetMillis = sunset.getTime();
571
+ if (isNaN(sunsetMillis)) {
572
+ return hd;
573
+ }
574
+ if (date.getTime() >= sunsetMillis) {
575
+ hd = hd.next();
576
+ }
577
+ return hd;
578
+ }
579
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,9 @@
1
+ /* eslint-disable require-jsdoc */
2
+ import fs from 'fs';
3
+ const inpath = process.argv[2];
4
+ const outpath = process.argv[3];
5
+ const contents = fs.readFileSync(inpath).toString();
6
+ const manifest = JSON.parse(contents);
7
+ const line = `/** DO NOT EDIT THIS AUTO-GENERATED FILE! */
8
+ export const version = '${manifest.version}';\n`;
9
+ fs.writeFileSync(outpath, line, { flags: 'w' });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hebcal/core",
3
- "version": "6.0.5",
3
+ "version": "6.0.7",
4
4
  "author": "Michael J. Radwin (https://github.com/mjradwin)",
5
5
  "contributors": [
6
6
  "Eyal Schachter (https://github.com/Scimonster)",
@@ -61,25 +61,28 @@
61
61
  "coverage": "vitest --coverage",
62
62
  "test": "vitest",
63
63
  "clean": "gts clean",
64
- "fix": "gts fix"
64
+ "fix": "gts fix",
65
+ "compile": "tsc",
66
+ "prepare": "npm run compile",
67
+ "posttest": "npm run lint"
65
68
  },
66
69
  "license": "GPL-2.0",
67
70
  "devDependencies": {
68
71
  "@rollup/plugin-node-resolve": "^16.0.3",
69
72
  "@rollup/plugin-terser": "^0.4.4",
70
73
  "@rollup/plugin-typescript": "^12.3.0",
71
- "@types/node": "^24.9.2",
72
- "@vitest/coverage-v8": "^4.0.5",
73
- "core-js": "^3.46.0",
74
- "gettext-parser": "^8.0.0",
74
+ "@types/node": "^25.0.3",
75
+ "@vitest/coverage-v8": "^4.0.16",
76
+ "core-js": "^3.47.0",
77
+ "gettext-parser": "^9.0.0",
75
78
  "gts": "^6.0.2",
76
79
  "pretty-bytes": "^7.1.0",
77
- "rollup": "^4.52.5",
80
+ "rollup": "^4.54.0",
78
81
  "rollup-plugin-bundle-size": "^1.0.3",
79
82
  "rollup-plugin-visualizer": "^6.0.5",
80
- "typedoc": "^0.28.14",
83
+ "typedoc": "^0.28.15",
81
84
  "typescript": "^5.9.3",
82
- "vitest": "^4.0.5"
85
+ "vitest": "^4.0.16"
83
86
  },
84
87
  "dependencies": {
85
88
  "@hebcal/hdate": "^0.21.1",