Skip to main content

rust_zmanim/
complex_zmanim_calendar.rs

1//! The [ComplexZmanimCalendar] struct is stateful and has many premade *zmanim*
2//! calculations, both conveniences built on the [zmanim_calculator] API.
3
4use crate::util::geolocation::GeoLocation;
5use crate::zmanim_calculator;
6use crate::zmanim_calculator::{ZmanOffset, ZmanOffset::*};
7
8use chrono::DateTime;
9use chrono::TimeDelta;
10use chrono_tz::Tz;
11
12/// Struct to store a 4-dimensional location and settings, to simplify getting
13/// many *zmanim* for the same location. Has premade methods for many common
14/// (and uncommon) *zmanim*. **Elevation based *zmanim* (even sunrise and
15/// sunset) should not be used *lekula* without the guidance of a *posek***. See
16/// the documentation of [zmanim_calculator] for more details.
17pub struct ComplexZmanimCalendar {
18    /// Location at which to calculate *zmanim*
19    pub geo_location: GeoLocation,
20
21    /// Day for which to calculate *zmanim*. Time does not (should not) affect
22    /// the calculations
23    pub date: DateTime<Tz>,
24
25    /// When to account for elevation. See [UseElevation]
26    pub use_elevation: UseElevation,
27}
28
29/// I tried to put the methods in some sort of order just to keep it organized.
30/// Currently, it's:
31/// 1. Basics from [zmanim_calculator]
32/// 2. Named *shitos*, no order
33/// 3. MGA degrees-based, ascending
34/// 4. MGA minutes-based, zmanis after fixed (e.g. 72 minutes, 72 minutes
35///    zmanis, 90 minutes...)
36/// 5. Other *zmanim*, sorted by time of day (*Misheyakir*, *Hanetz*,
37///    *Chatzos*...)
38///
39/// All *shaos zmaniyos* are in minutes
40impl ComplexZmanimCalendar {
41    // Basics
42    /// Returns *alos hashachar* (dawn) based on either declination of the sun
43    /// below the horizon, a fixed time offset, or a minutes *zmaniyos*
44    /// (temporal minutes) offset before sunrise
45    pub fn alos(&self, offset: &ZmanOffset) -> Option<DateTime<Tz>> {
46        let use_elevation = self.use_elevation.to_bool(false);
47        zmanim_calculator::alos(&self.date, &self.geo_location, use_elevation, offset)
48    }
49
50    /// Returns *hanetz*, or sunrise. Will be elevation-adjusted or not
51    /// depending on `use_elevation`
52    pub fn hanetz(&self) -> Option<DateTime<Tz>> {
53        let use_elevation = self.use_elevation.to_bool(true);
54        zmanim_calculator::hanetz(&self.date, &self.geo_location, use_elevation)
55    }
56
57    /// Returns the latest *zman krias shema* (time to recite *Shema* in the
58    /// morning) according to the opinion of the *Magen Avraham* (MGA) based on
59    /// *alos* and *tzais* being given offset from sunrise and sunset,
60    /// respectively.
61    pub fn sof_zman_shema_mga(&self, offset: &ZmanOffset) -> Option<DateTime<Tz>> {
62        Some(zmanim_calculator::sof_zman_shema(
63            &self.alos(offset)?,
64            &self.tzais(offset)?,
65        ))
66    }
67
68    /// Returns the latest *zman tefila* (time to recite *shacharis* in the
69    /// morning) according to the opinion of the *Magen Avraham* (MGA) based on
70    /// *alos* and *tzais* being the given offset from sunrise and sunset,
71    /// respectively.
72    pub fn sof_zman_tefila_mga(&self, offset: &ZmanOffset) -> Option<DateTime<Tz>> {
73        Some(zmanim_calculator::sof_zman_tefila(
74            &self.alos(offset)?,
75            &self.tzais(offset)?,
76        ))
77    }
78
79    /// Returns Astronomical *chatzos*
80    pub fn chatzos(&self) -> Option<DateTime<Tz>> {
81        zmanim_calculator::chatzos(&self.date, &self.geo_location)
82    }
83
84    /// Returns *mincha gedola* according to the opinion of the *Magen Avraham*
85    /// (MGA) based on *alos* and *tzais* being the given offset from sunrise
86    /// and sunset, respectively.
87    pub fn mincha_gedola_mga(&self, offset: &ZmanOffset) -> Option<DateTime<Tz>> {
88        Some(zmanim_calculator::mincha_gedola(
89            &self.alos(offset)?,
90            &self.tzais(offset)?,
91        ))
92    }
93
94    /// Returns *mincha ketana* according to the opinion of the *Magen Avraham*
95    /// (MGA) based on *alos* and *tzais* being the given offset from sunrise
96    /// and sunset, respectively.
97    pub fn mincha_ketana_mga(&self, offset: &ZmanOffset) -> Option<DateTime<Tz>> {
98        Some(zmanim_calculator::mincha_ketana(
99            &self.alos(offset)?,
100            &self.tzais(offset)?,
101        ))
102    }
103
104    /// Returns *plag hamincha* according to the opinion of the *Magen Avraham*
105    /// (MGA) based on *alos* and *tzais* being the given offset from sunrise
106    /// and sunset, respectively.
107    pub fn plag_mga(&self, offset: &ZmanOffset) -> Option<DateTime<Tz>> {
108        Some(zmanim_calculator::plag_hamincha(
109            &self.alos(offset)?,
110            &self.tzais(offset)?,
111        ))
112    }
113
114    /// Returns *mincha gedola* calculated as 30 minutes after *chatzos* and not
115    /// 1/2 of a *shaah zmanis* after *chatzos* as calculated by
116    /// [zmanim_calculator::mincha_gedola]. See
117    /// [zmanim_calculator::mincha_gedola_30_minutes] for more details
118    pub fn mincha_gedola_30_minutes(&self) -> Option<DateTime<Tz>> {
119        zmanim_calculator::mincha_gedola_30_minutes(&self.date, &self.geo_location)
120    }
121
122    /// Returns *shkia*, or sunset. Will be elevation-adjusted or not depending
123    /// on `use_elevation`
124    pub fn shkia(&self) -> Option<DateTime<Tz>> {
125        let use_elevation = self.use_elevation.to_bool(true);
126        zmanim_calculator::shkia(&self.date, &self.geo_location, use_elevation)
127    }
128
129    /// Returns *tzais* (nightfall) based on either declination of the sun below
130    /// the horizon, a fixed time offset, or a minutes *zmaniyos* (temporal
131    /// minutes) offset after sunset
132    pub fn tzais(&self, offset: &ZmanOffset) -> Option<DateTime<Tz>> {
133        let use_elevation = self.use_elevation.to_bool(false);
134        zmanim_calculator::tzais(&self.date, &self.geo_location, use_elevation, offset)
135    }
136
137    // GRA
138    /// Returns the latest *zman shema* (time to recite *Shema* in the morning)
139    /// that is 3 *shaos zmaniyos* (solar hours) after
140    /// [sunrise](crate::astronomical_calculator::sunrise) or [sea
141    /// level sunrise](crate::astronomical_calculator::sea_level_sunrise)
142    /// (depending on the `use_elevation`) according the GRA. The day is
143    /// calculated from [sea level
144    /// sunrise](crate::astronomical_calculator::sea_level_sunrise) to
145    /// [sea level sunset](crate::astronomical_calculator::sea_level_sunset) or
146    /// from [sunrise](crate::astronomical_calculator::sunrise) to
147    /// [sunset](crate::astronomical_calculator::sunset) (depending on
148    /// `use_elevation`)
149    pub fn sof_zman_shema_gra(&self) -> Option<DateTime<Tz>> {
150        Some(zmanim_calculator::sof_zman_shema(
151            &self.hanetz()?,
152            &self.shkia()?,
153        ))
154    }
155
156    /// Returns the latest *zman tefila* (time to recite *shacharis* in the
157    /// morning) that is 4 *shaos zmaniyos* (solar hours) after
158    /// [sunrise](crate::astronomical_calculator::sunrise) or [sea level
159    /// sunrise](crate::astronomical_calculator::sea_level_sunrise) (depending
160    /// on the `use_elevation`) according GRA.
161    ///
162    /// The day is calculated from [sea level
163    /// sunrise](crate::astronomical_calculator::sea_level_sunrise) to
164    /// [sea level sunset](crate::astronomical_calculator::sea_level_sunset) or
165    /// from [sunrise](crate::astronomical_calculator::sunrise) to
166    /// [sunset](crate::astronomical_calculator::sunset) (depending on
167    /// `use_elevation`)
168    pub fn sof_zman_tefila_gra(&self) -> Option<DateTime<Tz>> {
169        Some(zmanim_calculator::sof_zman_tefila(
170            &self.hanetz()?,
171            &self.shkia()?,
172        ))
173    }
174
175    /// This method returns the latest time for burning *chametz* on *Erev
176    /// Pesach* according to the opinion of the GRA. This time is 5 hours into
177    /// the day based on the opinion of the GRA that the day is calculated from
178    /// sunrise to sunset. Since this library does not implement a calendar,
179    /// this method will return the *zman* any day of the year.
180    pub fn sof_zman_biur_chametz_gra(&self) -> Option<DateTime<Tz>> {
181        Some(self.hanetz()? + (self.shaah_zmanis_gra()? * 5))
182    }
183
184    /// Returns *mincha gedola* calculated as 6.5 * *shaos zmaniyos*
185    /// (solar hours) after sunrise or sea level sunrise (depending on
186    /// `use_elevation`), according to the GRA.
187    pub fn mincha_gedola_gra(&self) -> Option<DateTime<Tz>> {
188        Some(zmanim_calculator::mincha_gedola(
189            &self.hanetz()?,
190            &self.shkia()?,
191        ))
192    }
193
194    /// Returns the later of
195    /// [mincha_gedola_gra](ComplexZmanimCalendar::mincha_gedola_gra)
196    /// and
197    /// [mincha_gedola_30_minutes](ComplexZmanimCalendar::mincha_gedola_30_minutes)
198    /// . In the winter when 1/2 of a
199    /// [GRA *shaah zmanis*](ComplexZmanimCalendar::shaah_zmanis_gra)
200    /// is less than 30 minutes
201    /// [mincha_gedola_30_minutes](ComplexZmanimCalendar::mincha_gedola_30_minutes)
202    /// will be returned, otherwise
203    /// [mincha_gedola_gra](ComplexZmanimCalendar::mincha_gedola_gra)
204    ///  will be returned
205    pub fn mincha_gedola_gra_greater_than_30_minutes(&self) -> Option<DateTime<Tz>> {
206        let mg_30 = self.mincha_gedola_30_minutes()?;
207        let mg_gra = self.mincha_gedola_gra()?;
208        Some(if mg_30 > mg_gra { mg_30 } else { mg_gra })
209    }
210
211    /// A method for calculating *samuch lemincha ketana*, / near *mincha
212    /// ketana* time that is half an hour before [*mincha
213    /// ketana*](ComplexZmanimCalendar::mincha_ketana_gra) or is 9 *shaos
214    /// zmaniyos* (solar hours) after sunrise or sea level sunrise (depending on
215    /// `use_elevation`), calculated according to the GRA using a day starting
216    /// at sunrise and ending at sunset. This is the time that eating or other
217    /// activity can't begin prior to praying *mincha*. See the *Mechaber* and
218    /// *Mishna Berurah* 232 and 249:2.
219    pub fn samuch_lemincha_ketana_gra(&self) -> Option<DateTime<Tz>> {
220        Some(self.hanetz()? + (self.shaah_zmanis_gra()? * 9))
221    }
222
223    /// Returns *mincha ketana* calculated as 9.5 * *shaos zmaniyos*
224    /// (solar hours) after sunrise or sea level sunrise (depending on
225    /// `use_elevation`), according to the GRA.
226    pub fn mincha_ketana_gra(&self) -> Option<DateTime<Tz>> {
227        Some(zmanim_calculator::mincha_ketana(
228            &self.hanetz()?,
229            &self.shkia()?,
230        ))
231    }
232
233    /// Returns *plag hamincha* calculated as 10.75 * *shaos zmaniyos*
234    /// (solar hours) after sunrise or sea level sunrise (depending on
235    /// `use_elevation`), according to the GRA.
236    pub fn plag_gra(&self) -> Option<DateTime<Tz>> {
237        Some(zmanim_calculator::plag_hamincha(
238            &self.hanetz()?,
239            &self.shkia()?,
240        ))
241    }
242
243    /// Returns a *shaah zmanis* according to the opinion of the GRA.
244    ///
245    /// This calculation divides the day based on the opinion of the *GRA* that
246    /// the day runs from from [sea level
247    /// sunrise](crate::astronomical_calculator::sea_level_sunrise) to
248    /// [sea level sunset](crate::astronomical_calculator::sea_level_sunset) or
249    /// [sunrise](crate::astronomical_calculator::sunrise) to
250    /// [sunset](crate::astronomical_calculator::sunset) (depending on
251    /// `use_elevation`). The day is split into 12 equal parts with each one
252    /// being a *shaah zmanis*
253    pub fn shaah_zmanis_gra(&self) -> Option<TimeDelta> {
254        Some(zmanim_calculator::shaah_zmanis(
255            &self.hanetz()?,
256            &self.shkia()?,
257        ))
258    }
259
260    // Baal HaTanya
261    /// Returns the *Baal Hatanya*'s *alos* (dawn) calculated as the time when
262    /// the sun is 16.9&deg; below the eastern geometric horizon before sunrise.
263    /// It is based on the calculation that the time between dawn and
264    /// *netz amiti* (sunrise) is 72 minutes, the time that is takes to walk 4
265    /// *mil* at 18 minutes a *mil* (*Rambam* and others). The sun's
266    /// position at 72 minutes before *netz amiti* (sunrise) in Jerusalem
267    /// around the equinox / equilux is 16.9&deg; below geometric zenith.
268    pub fn alos_baal_hatanya(&self) -> Option<DateTime<Tz>> {
269        self.alos(&Degrees(16.9))
270    }
271
272    /// Returns the *Baal Hatanya*'s *netz amiti* (sunrise) without elevation
273    /// adjustment. This forms the base for the *Baal Hatanya*'s dawn-based
274    /// calculations that are calculated as a dip below the horizon before
275    /// sunrise. According to the *Baal Hatanya*, *netz amiti*, or true
276    /// (halachic) sunrise, is when the top of the sun's disk is visible at
277    /// an elevation similar to the mountains of *Eretz Yisrael*. The time
278    /// is calculated as the point at which the center of the sun's disk is
279    /// 1.583&deg; below the horizon. This degree-based calculation can be found
280    /// in Rabbi Shalom DovBer Levine's commentary on The *Baal Hatanya*'s
281    /// *Seder Hachnasas Shabbos*. From an elevation of 546 meters, the top
282    /// of *Har Hacarmel*, the sun disappears when it is 1&deg; 35' or
283    /// 1.583&deg; below the sea level horizon. This in turn is based on the
284    /// *Gemara Shabbos* 35a. There are other opinions brought down by Rabbi
285    /// Levine, including Rabbi Yosef Yitzchok Feigelstock who calculates it
286    /// as the degrees below the horizon 4 minutes after sunset in
287    /// *Yerushalayim* (on the equinox). That is brought down as 1.583&deg;.
288    /// This is identical to the 1&deg; 35' *zman* and is probably a typo and
289    /// should be 1.683&deg;. These calculations are used by most *Chabad*
290    /// calendars that use the *Baal Hatanya*'s *zmanim*. Note: *netz amiti*
291    /// is used only for calculating certain *zmanim*, and is intentionally
292    /// unpublished. For practical purposes, daytime *mitzvos* like *shofar*
293    /// and *lulav* should not be done until after the published time for
294    /// *netz* / sunrise.
295    fn sunrise_baal_hatanya(&self) -> Option<DateTime<Tz>> {
296        self.alos(&Degrees(1.583))
297    }
298
299    /// Returns the the *Baal Hatanya*'s *sof *zman* krias shema*
300    /// (latest time to recite *Shema* in the morning). This time is 3
301    /// *shaos zmaniyos* (solar hours) after *netz amiti* (sunrise) based on
302    /// the opinion of the *Baal Hatanya* that the day is calculated from
303    /// sunrise to sunset. This returns the time
304    /// `self.sunrise_baal_hatanya() + (self.shaah_zmanis_baal_hatanya()? *
305    /// 3.0)`
306    pub fn sof_zman_shema_baal_hatanya(&self) -> Option<DateTime<Tz>> {
307        Some(zmanim_calculator::sof_zman_shema(
308            &self.sunrise_baal_hatanya()?,
309            &self.sunset_baal_hatanya()?,
310        ))
311    }
312
313    /// Returns the the *Baal Hatanya*'s *sof *zman* tefila* (latest
314    /// time to recite the morning prayers). This time is 4 *shaos zmaniyos*
315    /// (solar hours) after *netz amiti* (sunrise) based on the opinion of
316    /// the *Baal Hatanya* that the day is calculated from sunrise to
317    /// sunset. This returns the time `self.sunrise_baal_hatanya() +
318    /// (self.shaah_zmanis_baal_hatanya()? * 4.0)`
319    pub fn sof_zman_tefila_baal_hatanya(&self) -> Option<DateTime<Tz>> {
320        Some(zmanim_calculator::sof_zman_tefila(
321            &self.sunrise_baal_hatanya()?,
322            &self.sunset_baal_hatanya()?,
323        ))
324    }
325
326    /// This method returns the latest time for burning *chametz* on *Erev
327    /// Pesach* according to the opinion of the Baal Hatanya. This time is 5
328    /// hours into the day based on the opinion of the Baal Hatanya that the day
329    /// is calculated from slightly before sunrise to slightly after sunset.
330    /// Since this library does not implement a calendar, this method will
331    /// return the *zman* any day of the year.
332    pub fn sof_zman_biur_chametz_baal_hatanya(&self) -> Option<DateTime<Tz>> {
333        Some(self.sunrise_baal_hatanya()? + (self.shaah_zmanis_baal_hatanya()? * 5))
334    }
335
336    /// Returns the the *Baal Hatanya*'s *mincha gedola*. *Mincha
337    /// gedola* is the earliest time one can pray *mincha*. The *Rambam* is
338    /// of the opinion that it is better to delay *mincha* until *mincha
339    /// ketana* while the *Rash*, *Tur*, GRA and others are of the opinion
340    /// that *mincha* can be prayed *lechatchila* starting at *mincha
341    /// gedola*. This is calculated as 6.5 sea level solar hours after *netz
342    /// amiti* (sunrise). This calculation is based on the opinion of the
343    /// *Baal Hatanya* that the day is calculated from sunrise to
344    /// sunset. This returns the time `self.sunrise_baal_hatanya() +
345    /// (self.shaah_zmanis_baal_hatanya()? * 6.5)`
346    pub fn mincha_gedola_baal_hatanya(&self) -> Option<DateTime<Tz>> {
347        Some(zmanim_calculator::mincha_gedola(
348            &self.sunrise_baal_hatanya()?,
349            &self.sunset_baal_hatanya()?,
350        ))
351    }
352
353    /// Returns the later of
354    /// [mincha_gedola_baal_hatanya](ComplexZmanimCalendar::mincha_gedola_baal_hatanya)
355    /// and
356    /// [mincha_gedola_30_minutes](ComplexZmanimCalendar::mincha_gedola_30_minutes)
357    /// . In the winter when 1/2 of a
358    /// [*Baal Hatanya shaah
359    /// zmanis*](ComplexZmanimCalendar::shaah_zmanis_baal_hatanya)
360    /// is less than 30 minutes
361    /// [mincha_gedola_30_minutes](ComplexZmanimCalendar::mincha_gedola_30_minutes)
362    /// will be returned, otherwise
363    /// [mincha_gedola_baal_hatanya](ComplexZmanimCalendar::mincha_gedola_baal_hatanya)
364    ///  will be returned
365    pub fn mincha_gedola_baal_hatanya_greater_than_30_minutes(&self) -> Option<DateTime<Tz>> {
366        let mg_30 = self.mincha_gedola_30_minutes()?;
367        let mg_bht = self.mincha_gedola_baal_hatanya()?;
368        Some(if mg_30 > mg_bht { mg_30 } else { mg_bht })
369    }
370
371    /// Returns the *Baal Hatanya*'s *mincha ketana*. This is the
372    /// preferred earliest time to pray *mincha* in the opinion of the *Rambam*
373    /// and others. For more information on this see the documentation on
374    /// *mincha gedola*. This is calculated as 9.5 sea level solar hours after
375    /// *netz amiti* (sunrise). This calculation is calculated based on the
376    /// opinion of the *Baal Hatanya* that the day is calculated from sunrise to
377    /// sunset. This returns the time `self.sunrise_baal_hatanya() +
378    /// (self.shaah_zmanis_baal_hatanya()? * 9.5)`
379    pub fn mincha_ketana_baal_hatanya(&self) -> Option<DateTime<Tz>> {
380        Some(zmanim_calculator::mincha_ketana(
381            &self.sunrise_baal_hatanya()?,
382            &self.sunset_baal_hatanya()?,
383        ))
384    }
385
386    /// Returns the *Baal Hatanya*'s *plag hamincha*. This is
387    /// calculated as 10.75 sea level solar hours after *netz amiti* (sunrise).
388    /// This calculation is calculated based on the opinion of the *Baal
389    /// Hatanya* that the day is calculated from sunrise to sunset. This returns
390    /// the time `self.sunrise_baal_hatanya() +
391    /// (self.shaah_zmanis_baal_hatanya()? * 10.75)`
392    pub fn plag_baal_hatanya(&self) -> Option<DateTime<Tz>> {
393        Some(zmanim_calculator::plag_hamincha(
394            &self.sunrise_baal_hatanya()?,
395            &self.sunset_baal_hatanya()?,
396        ))
397    }
398
399    /// Returns the *Baal Hatanya*'s *shkiah amiti* (sunset)
400    /// without elevation adjustment. This forms the base for the *Baal
401    /// Hatanya*'s dusk-based calculations that are calculated as a dip
402    /// below the horizon after sunset. According to the *Baal Hatanya*,
403    /// *shkiah amiti*, true (halachic) sunset, is when the top of the sun's
404    /// disk disappears from view at an elevation similar to the mountains
405    /// of *Eretz Yisrael*. This time is calculated as the point at which
406    /// the center of the sun's disk is 1.583 degrees below the horizon.
407    /// Note: *shkiah amiti* is used only for calculating certain *zmanim*,
408    /// and is intentionally unpublished. For practical purposes, all
409    /// daytime *mitzvos* should be completed before the published time for
410    /// *shkiah* / sunset.
411    fn sunset_baal_hatanya(&self) -> Option<DateTime<Tz>> {
412        self.tzais(&Degrees(1.583))
413    }
414
415    /// Returns *tzais* (nightfall) when the sun is 6&deg; below
416    /// the western geometric horizon (90&deg;) after sunset. This calculation
417    /// is based on the position of the sun 24 minutes after sunset in Jerusalem
418    /// around the equinox / equilux, which is 6&deg; below geometric zenith.
419    pub fn tzais_baal_hatanya(&self) -> Option<DateTime<Tz>> {
420        self.tzais(&Degrees(6.0))
421    }
422
423    /// Returns the *Baal Hatanya*'s a *shaah zmanis* (temporal hour). This
424    /// forms the base for the *Baal Hatanya*'s day based calculations that are
425    /// calculated as a 1.583&deg; dip below the horizon after sunset. According
426    /// to the *Baal Hatanya*, *shkiah amiti*, true (halachic) sunset, is when
427    /// the top of the sun's disk disappears from view at an elevation similar
428    /// to the mountains of *Eretz Yisrael*. This time is calculated as the
429    /// point at which the center of the sun's disk is 1.583 degrees below the
430    /// horizon. A method that returns a *shaah zmanis* (temporal hour)
431    /// calculated based on the *Baal Hatanya*'s *netz amiti* and *shkiah amiti*
432    /// using a dip of 1.583&deg; below the sea level horizon. This calculation
433    /// divides the day based on the opinion of the *Baal Hatanya* that the day
434    /// runs from *netz amiti* to *shkiah amiti*. The calculations are based on
435    /// a day from sea level *netz amiti* to sea level *shkiah amiti*. The day
436    /// is split into 12 equal parts with each one being a *shaah zmanis*.
437    pub fn shaah_zmanis_baal_hatanya(&self) -> Option<TimeDelta> {
438        Some(zmanim_calculator::shaah_zmanis(
439            &self.sunrise_baal_hatanya()?,
440            &self.sunset_baal_hatanya()?,
441        ))
442    }
443
444    // Rav Moshe Feinstein
445    /// Returns fixed local *chatzos*. See
446    /// [zmanim_calculator::fixed_local_chatzos] for more details
447    pub fn fixed_local_chatzos(&self) -> Option<DateTime<Tz>> {
448        zmanim_calculator::fixed_local_chatzos(&self.date, &self.geo_location)
449    }
450
451    /// This method returns Rav Moshe Feinstein's opinion of the calculation of
452    /// *sof zman krias shema* (latest time to recite *Shema* in the morning)
453    /// according to the opinion of the *Magen Avraham* (MGA) that the day is
454    /// calculated from dawn to nightfall, but calculated using the first half
455    /// of the day only. The half a day starts at *alos* defined as 18&deg; and
456    /// ends at fixed local *chatzos*. *Sof Zman Shema* is 3 *shaos
457    /// zmaniyos* (solar hours) after *alos* or half of this half-day.
458    pub fn sof_zman_shema_mga_18_degrees_to_fixed_local_chatzos(&self) -> Option<DateTime<Tz>> {
459        let alos = self.alos_18_degrees()?;
460        let offset = (self.fixed_local_chatzos()? - alos) / 2;
461        Some(alos + offset)
462    }
463
464    /// This method returns Rav Moshe Feinstein's opinion of the calculation of
465    /// *sof zman krias shema* (latest time to recite *Shema* in the morning)
466    /// according to the opinion of the *Magen Avraham* (MGA) that the day is
467    /// calculated from dawn to nightfall, but calculated using the first half
468    /// of the day only. The half a day starts at *alos* defined as 16.1&deg;
469    /// and ends at fixed local *chatzos*. *Sof Zman Shema* is 3 *shaos
470    /// zmaniyos* (solar hours) after this *alos* or half of this half-day.
471    pub fn sof_zman_shema_mga_16_1_degrees_to_fixed_local_chatzos(&self) -> Option<DateTime<Tz>> {
472        let alos = self.alos_16_1_degrees()?;
473        let offset = (self.fixed_local_chatzos()? - alos) / 2;
474        Some(alos + offset)
475    }
476
477    /// This method returns Rav Moshe Feinstein's opinion of the calculation of
478    /// *sof zman krias shema* (latest time to recite *Shema* in the morning)
479    /// according to the opinion of the *Magen Avraham* (MGA) that the day is
480    /// calculated from dawn to nightfall, but calculated using the first half
481    /// of the day only. The half a day starts at *alos* defined as 90 minutes
482    /// before sunrise and ends at fixed local *chatzos*. *Sof Zman Shema* is 3
483    /// *shaos zmaniyos* (solar hours) after this *alos* or half of this
484    /// half-day.
485    pub fn sof_zman_shema_mga_90_minutes_to_fixed_local_chatzos(&self) -> Option<DateTime<Tz>> {
486        let alos = self.alos_90_minutes()?;
487        let offset = (self.fixed_local_chatzos()? - alos) / 2;
488        Some(alos + offset)
489    }
490
491    /// This method returns Rav Moshe Feinstein's opinion of the calculation of
492    /// *sof zman krias shema* (latest time to recite *Shema* in the morning)
493    /// according to the opinion of the *Magen Avraham* (MGA) that the day is
494    /// calculated from dawn to nightfall, but calculated using the first half
495    /// of the day only. The half a day starts at *alos* defined as 72 minutes
496    /// before sunrise and ends at fixed local *chatzos*. *Sof Zman Shema* is 3
497    /// *shaos zmaniyos* (solar hours) after this *alos* or half of this
498    /// half-day.
499    pub fn sof_zman_shema_mga_72_minutes_to_fixed_local_chatzos(&self) -> Option<DateTime<Tz>> {
500        let alos = self.alos_72_minutes()?;
501        let offset = (self.fixed_local_chatzos()? - alos) / 2;
502        Some(alos + offset)
503    }
504
505    /// This method returns Rav Moshe Feinstein's opinion of the calculation of
506    /// *sof zman krias shema* (latest time to recite *Shema* in the morning)
507    /// according to the opinion of the GRA that the day is calculated from
508    /// sunrise to sunset, but calculated using the first half of the day only.
509    /// The half a day starts at sunrise and ends at fixed local *chatzos*. Sof
510    /// zman Shema is 3 *shaos zmaniyos* (solar hours) after sunrise or half of
511    /// this half-day.
512    pub fn sof_zman_shema_gra_sunrise_to_fixed_local_chatzos(&self) -> Option<DateTime<Tz>> {
513        let alos = self.hanetz()?;
514        let offset = (self.fixed_local_chatzos()? - alos) / 2;
515        Some(alos + offset)
516    }
517
518    /// This method returns Rav Moshe Feinstein's opinion of the calculation of
519    /// *sof zman tefila* (the latest time to recite the morning
520    /// prayers) according to the opinion of the GRA that the day is calculated
521    /// from sunrise to sunset, but calculated using the first half of the day
522    /// only. The half a day starts at sunrise and ends at fixed local
523    /// *chatzos*. Sof zman tefila is 4 *shaos zmaniyos* (solar hours) after
524    /// sunrise or 2/3 of this half-day.
525    pub fn sof_zman_tefila_gra_sunrise_to_fixed_local_chatzos(&self) -> Option<DateTime<Tz>> {
526        let alos = self.hanetz()?;
527        let offset = ((self.fixed_local_chatzos()? - alos) * 2) / 3;
528        Some(alos + offset)
529    }
530
531    /// This method returns Rav Moshe Feinstein's opinion of the calculation of
532    /// mincha gedola, the earliest time one can pray mincha calculated
533    /// according to the GRA that is 30 minutes after fixed local *chatzos*.
534    pub fn mincha_gedola_gra_fixed_local_chatzos_30_minutes(&self) -> Option<DateTime<Tz>> {
535        Some(self.fixed_local_chatzos()? + TimeDelta::minutes(30))
536    }
537
538    /// This method returns Rav Moshe Feinstein's opinion of the calculation of
539    /// mincha ketana (the preferred time to recite the mincha prayers according
540    /// to the opinion of the Rambam and others) calculated according to the GRA
541    /// that is 3.5 *shaos zmaniyos* (solar hours) after fixed local *chatzos*.
542    pub fn mincha_ketana_gra_fixed_local_chatzos_to_sunset(&self) -> Option<DateTime<Tz>> {
543        let chatzos = self.fixed_local_chatzos()?;
544        let half_shaah = (self.shkia()? - chatzos) / 12;
545        Some(chatzos + (half_shaah * 7))
546    }
547
548    /// This method returns Rav Moshe Feinstein's opinion of the calculation of
549    /// plag hamincha. This method returns plag hamincha calculated according to
550    /// the GRA that the day ends at sunset and is 4.75 *shaos zmaniyos* (solar
551    /// hours) after fixed local *chatzos*.
552    pub fn plag_gra_fixed_local_chatzos_to_sunset(&self) -> Option<DateTime<Tz>> {
553        let chatzos = self.fixed_local_chatzos()?;
554        // (19/24) == (4.75/6)
555        let quarter_shaah = (self.shkia()? - chatzos) / 24;
556        Some(chatzos + (quarter_shaah * 19))
557    }
558
559    /// Method to return *tzais* (dusk) calculated as 50 minutes after sea level
560    /// sunset. This method returns *tzais* (nightfall) based on the opinion of
561    /// Rabbi Moshe Feinstein for the New York area. This time should not be
562    /// used for latitudes other than ones similar to the latitude of the NY
563    /// area.
564    pub fn tzais_50_minutes(&self) -> Option<DateTime<Tz>> {
565        self.tzais(&Minutes(50.0))
566    }
567
568    // Ahavat Shalom
569    /// Returns the time of *mincha gedola* based on the opinion of
570    /// Rabbi Yaakov Moshe Hillel as published in the luach of the Bais Horaah
571    /// of Yeshivat Chevrat Ahavat Shalom that *mincha gedola* is calculated as
572    /// half a *shaah zmanis* after *chatzos* with *shaos zmaniyos* calculated
573    /// based on a day starting 72 minutes before sunrise (alos 16.1&deg;) and
574    /// ending 13.5 minutes after sunset (*tzais* 3.7&deg;). *Mincha gedola* is
575    /// the earliest time to pray *mincha*. The later of this time or 30
576    /// clock minutes after *chatzos* is returned. See
577    /// [mincha_gedola_gra_greater_than_30_minutes](ComplexZmanimCalendar::mincha_gedola_gra_greater_than_30_minutes)
578    /// (though that calculation is based on *mincha gedola* GRA). For more
579    /// information about *mincha gedola* see the documentation on [*mincha
580    /// gedola*](zmanim_calculator::mincha_gedola).
581    pub fn mincha_gedola_ahavat_shalom(&self) -> Option<DateTime<Tz>> {
582        let mg_as = self.chatzos()? + (self.shaah_zmanis_alos_16_1_to_tzais_3_7()? / 2);
583        let mg_30 = self.mincha_gedola_30_minutes()?;
584        Some(if mg_30 > mg_as { mg_30 } else { mg_as })
585    }
586
587    /// Returns the time of *mincha ketana* based on the opinion of
588    /// Rabbi Yaakov Moshe Hillel as published in the luach of the Bais Horaah
589    /// of Yeshivat Chevrat Ahavat Shalom that *mincha ketana* is calculated as
590    /// 2.5 *shaos zmaniyos* before *tzais* 3.8&deg; with *shaos zmaniyos*
591    /// calculated based on a day starting at *alos* 16.1&deg; and ending at
592    /// *tzais* 3.8&deg;. *Mincha ketana* is the preferred earliest time to
593    /// pray *mincha* according to the opinion of the *Rambam* and others.
594    /// For more information on this see the documentation on [*mincha
595    /// gedola*](zmanim_calculator::mincha_gedola).
596    pub fn mincha_ketana_ahavat_shalom(&self) -> Option<DateTime<Tz>> {
597        Some(zmanim_calculator::mincha_ketana(
598            &self.alos_16_1_degrees()?,
599            &self.tzais_geonim_3_8_degrees()?,
600        ))
601    }
602
603    /// Returns the time of *plag hamincha* based on the opinion of
604    /// Rabbi Yaakov Moshe Hillel as published in the luach of the Bais Horaah
605    /// of Yeshivat Chevrat Ahavat Shalom that that *plag hamincha* is
606    /// calculated as 1.25 *shaos zmaniyos* before *tzais* 3.8&deg; with *shaos
607    /// zmaniyos* calculated based on a day starting at *alos* 16.1&deg; and
608    /// ending at *tzais* 3.8&deg;.
609    pub fn plag_ahavat_shalom(&self) -> Option<DateTime<Tz>> {
610        Some(zmanim_calculator::plag_hamincha(
611            &self.alos_16_1_degrees()?,
612            &self.tzais_geonim_3_8_degrees()?,
613        ))
614    }
615
616    /// Returns a *shaah zmanis* (temporal hour) used by some *zmanim*
617    /// according to the opinion of Rabbi Yaakov Moshe Hillel as published in
618    /// the luach of the Bais Horaah of Yeshivat Chevrat Ahavat Shalom that is
619    /// based on a day starting 72 minutes before sunrise in degrees (*alos*
620    /// 16.1&deg;) and ending 14 minutes after sunset in degrees (*tzais*
621    /// 3.8&deg;). This day is split into 12 equal parts with each part
622    /// being a *shaah zmanis*. Note that with this system, *chatzos*
623    /// (midday) will not be the point that the sun is halfway across the
624    /// sky. These *shaos zmaniyos* are used for *Mincha Ketana* and *Plag
625    /// Hamincha*. The 14 minutes are based on 3/4 of an 18 minute *mil*,
626    /// with half a minute added for Rav Yosi.
627    pub fn shaah_zmanis_alos_16_1_to_tzais_3_8(&self) -> Option<TimeDelta> {
628        Some(zmanim_calculator::shaah_zmanis(
629            &self.alos_16_1_degrees()?,
630            &self.tzais_geonim_3_8_degrees()?,
631        ))
632    }
633
634    /// Returns a *shaah zmanis* (temporal hour) used by some *zmanim*
635    /// according to the opinion of Rabbi Yaakov Moshe Hillel as published in
636    /// the luach of the Bais Horaah of Yeshivat Chevrat Ahavat Shalom that is
637    /// based on a day starting 72 minutes before sunrise in degrees (*alos*
638    /// 16.1&deg;) and ending 13.5 minutes after sunset in degrees (*tzais*
639    /// 3.7&deg;). This day is split into 12 equal parts with each part
640    /// being a *shaah zmanis*. Note that with this system, *chatzos*
641    /// (midday) will not be the point that the sun is halfway across the
642    /// sky. These *shaos zmaniyos* are used for *mincha gedola* calculation.
643    pub fn shaah_zmanis_alos_16_1_to_tzais_3_7(&self) -> Option<TimeDelta> {
644        Some(zmanim_calculator::shaah_zmanis(
645            &self.alos_16_1_degrees()?,
646            &self.tzais_geonim_3_7_degrees()?,
647        ))
648    }
649
650    // Ateret Torah
651    /// Returns the latest *zman krias shema* (time to recite
652    /// *Shema* in the morning) based on the calculation of *Chacham* Yosef
653    /// Harari-Raful of Yeshivat Ateret Torah, that the day starts 1/10th of the
654    /// day before sunrise and is usually calculated as ending 40 minutes after
655    /// sunset. *Shaos zmaniyos* are calculated based on this day and added to
656    /// *alos*to reach this time. This time is 3 *shaos zmaniyos* (temporal
657    /// hours) after *alos*72 zmaniyos. Note: Based on this calculation
658    /// *chatzos* will not be at midday.
659    pub fn sof_zman_shema_ateret_torah(&self) -> Option<DateTime<Tz>> {
660        Some(zmanim_calculator::sof_zman_shema(
661            &self.alos_72_minutes_zmanis()?,
662            &self.tzais_ateret_torah()?,
663        ))
664    }
665
666    /// Returns the latest *zman tefila* (time to recite the morning
667    /// prayers) based on the calculation of *Chacham* Yosef Harari-Raful of
668    /// Yeshivat Ateret Torah, that the day starts 1/10th of the day before
669    /// sunrise and is usually calculated as ending 40 minutes after sunset.
670    /// *Shaos zmaniyos* are calculated based on this day and added to *alos*to
671    /// reach this time. This time is 4 * *shaos zmaniyos* (temporal hours)
672    /// after *alos*72 *zmaniyos*. Note: Based on this calculation *chatzos*
673    /// will not be at midday.
674    pub fn sof_zman_tefila_ateret_torah(&self) -> Option<DateTime<Tz>> {
675        Some(zmanim_calculator::sof_zman_tefila(
676            &self.alos_72_minutes_zmanis()?,
677            &self.tzais_ateret_torah()?,
678        ))
679    }
680
681    /// Returns the time of *mincha gedola* based on the calculation of
682    /// *Chacham* Yosef Harari-Raful of Yeshivat Ateret Torah, that the day
683    /// starts 1/10th of the day before sunrise and is usually calculated as
684    /// ending 40 minutes after sunset. The *Rambam* is of the opinion that it
685    /// is better to delay *mincha* until *mincha ketana* while the Ra"sh, Tur,
686    /// GRA and others are of the opinion that mincha can be prayed lechatchila
687    /// starting at mincha gedola. For more information on this see the
688    /// documentation on [*mincha gedola*](zmanim_calculator::mincha_gedola).
689    /// This is calculated as 6.5 solar hours after *alos*. The calculation used
690    /// is 6.5 * [ComplexZmanimCalendar::shaah_zmanis_ateret_torah] after
691    /// *alos*.
692    pub fn mincha_gedola_ateret_torah(&self) -> Option<DateTime<Tz>> {
693        Some(zmanim_calculator::mincha_gedola(
694            &self.alos_72_minutes_zmanis()?,
695            &self.tzais_ateret_torah()?,
696        ))
697    }
698
699    /// Returns the time of *mincha ketana* based on the calculation of
700    /// *Chacham* Yosef Harari-Raful of Yeshivat Ateret Torah, that the day
701    /// starts 1/10th of the day before sunrise and is usually calculated as
702    /// ending 40 minutes after sunset. This is the preferred earliest time to
703    /// pray *mincha* according to the opinion of the *Rambam* and others. For
704    /// more information on this see the documentation on [*mincha
705    /// ketana*](zmanim_calculator::mincha_ketana). This is calculated as 9.5
706    /// solar hours after *alos*. The calculation used is 9.5 *
707    /// [ComplexZmanimCalendar::shaah_zmanis_ateret_torah] after *alos*.
708    pub fn mincha_ketana_ateret_torah(&self) -> Option<DateTime<Tz>> {
709        Some(zmanim_calculator::mincha_ketana(
710            &self.alos_72_minutes_zmanis()?,
711            &self.tzais_ateret_torah()?,
712        ))
713    }
714
715    /// Returns the time of *plag hamincha* based on the calculation
716    /// of *Chacham* Yosef Harari-Raful of Yeshivat Ateret Torah, that the day
717    /// starts 1/10th of the day before sunrise and is usually calculated as
718    /// ending 40 minutes after sunset. *Shaos zmaniyos* are calculated based on
719    /// this day and added to *alos* to reach this time. This time is 10.75
720    /// *shaos zmaniyos* (temporal hours) after dawn.
721    pub fn plag_ateret_torah(&self) -> Option<DateTime<Tz>> {
722        Some(zmanim_calculator::plag_hamincha(
723            &self.alos_72_minutes_zmanis()?,
724            &self.tzais_ateret_torah()?,
725        ))
726    }
727
728    /// Returns *tzais* calculated as 40 minutes after sunset. Please note that
729    /// *Chacham* Yosef Harari-Raful of Yeshivat Ateret Torah who uses this
730    /// time, does so only for calculating various other zmanei hayom such as
731    /// *Sof Zman Krias Shema* and *Plag Hamincha*. His calendars do not publish
732    /// a *zman* for *Tzais*. It should also be noted that *Chacham*
733    /// Harari-Raful provided a 25 minute *zman* for Israel. This API uses
734    /// 40 minutes year round in any place on the globe.
735    pub fn tzais_ateret_torah(&self) -> Option<DateTime<Tz>> {
736        self.tzais(&Minutes(40.0))
737    }
738
739    /// Returns a shaah zmanis (temporal hour) according to the opinion
740    /// of the *Chacham* Yosef Harari-Raful of Yeshivat Ateret Torah calculated
741    /// with *alos* being 1/10th of sunrise to sunset day, or 72 minutes
742    /// *zmaniyos* of such a day before sunrise, and *tzais* is usually
743    /// calculated as 40 minutes after sunset. This day is split into 12
744    /// equal parts with each part being a shaah zmanis. Note that with this
745    /// system, *chatzos* (midday) will not be the point that the sun is
746    /// halfway across the sky.
747    pub fn shaah_zmanis_ateret_torah(&self) -> Option<TimeDelta> {
748        Some(zmanim_calculator::shaah_zmanis(
749            &self.alos_72_minutes_zmanis()?,
750            &self.tzais_ateret_torah()?,
751        ))
752    }
753
754    // Shach
755    /// Returns the latest *zman krias shema* (time to recite *Shema* in the
756    /// morning) calculated as 3 hours (regular clock hours and not *shaos
757    /// zmaniyos*) before *chatzos*. Generally known as part of the "Komarno"
758    /// *zmanim* after Rav Yitzchak Eizik of Komarno, a proponent of this
759    /// calculation, it actually predates him a lot. It is the opinion of the
760    /// *Shach* in the *Nekudas Hakesef* (*Yoreh Deah* 184), Rav Moshe Lifshitz
761    /// in his commentary *Lechem Mishneh* on *Brachos* 1:2. It is next brought
762    /// down about 100 years later by the *Yaavetz* (in his *siddur*, *Mor
763    /// Uktziah Orach Chaim* 1, *Lechem Shamayim*, *Brachos* 1:2 and *She'elos
764    /// Yaavetz* vol. 1 no. 40), Rav Yitzchak Eizik of Komarno in the *Ma'aseh
765    /// Oreg* on *Mishnayos Brachos* 11:2, *Shevus Yaakov*, *Chasan Sofer* and
766    /// others. See *Yisrael Vehazmanim* vol. 1 7:3, page 55 - 62
767    pub fn sof_zman_shema_3_hrs_before_chatzos(&self) -> Option<DateTime<Tz>> {
768        Some(self.chatzos()? - TimeDelta::hours(3))
769    }
770
771    /// Returns the latest *zman* tefila (time to recite the morning prayers)
772    /// calculated as 2 hours before *chatzos*. This is based on the opinions
773    /// that calculate sof *zman* krias shema as [3 hours before
774    /// *chatzos*](ComplexZmanimCalendar::sof_zman_shema_3_hrs_before_chatzos).
775    pub fn sof_zman_tefila_2_hrs_before_chatzos(&self) -> Option<DateTime<Tz>> {
776        Some(self.chatzos()? - TimeDelta::hours(2))
777    }
778
779    // 16.1 degrees
780    /// Returns *alos* (dawn) calculated when the sun is 16.1&deg;
781    /// below the eastern geometric horizon before sunrise. This calculation
782    /// is based on the same calculation of 72 minutes but uses a
783    /// degree-based calculation instead of 72 exact minutes. This
784    /// calculation is based on the position of the sun 72 minutes before
785    /// sunrise in Jerusalem around the equinox / equilux, which calculates
786    /// to 16.1&deg; below geometric zenith.
787    pub fn alos_16_1_degrees(&self) -> Option<DateTime<Tz>> {
788        self.alos(&Degrees(16.1))
789    }
790
791    /// Returns the latest *zman krias shema* (time to recite
792    /// *Shema* in the morning) according to the opinion of the *Magen
793    /// Avraham* (MGA) based on *alos* being 16.1&deg; before sunrise. This time
794    /// is 3 *shaos zmaniyos* (solar hours) after dawn based on the opinion
795    /// of the MGA that the day is calculated from dawn to nightfall with
796    /// both being 16.1&deg; below sunrise or sunset. This returns the time of
797    /// `self.alos_16_1_degrees()? + (self.shaah_zmanis_16_1_degrees()? * 3.0)`
798    pub fn sof_zman_shema_mga_16_1_degrees(&self) -> Option<DateTime<Tz>> {
799        Some(zmanim_calculator::sof_zman_shema(
800            &self.alos_16_1_degrees()?,
801            &self.tzais_16_1_degrees()?,
802        ))
803    }
804
805    /// Returns the latest *zman tefila* (time to recite the morning
806    /// prayers) according to the opinion of the *Magen Avraham* (MGA) based on
807    /// *alos*being 16.1&deg; before sunrise. This time is 4 *shaos zmaniyos*
808    /// (solar hours) after dawn based on the opinion of the MGA that the
809    /// day is calculated from dawn to nightfall with both being 16.1&deg;
810    /// below sunrise or sunset. This returns the time of
811    /// `self.alos_16_1_degrees()? + (self.shaah_zmanis_16_1_degrees()? *
812    /// 4.0)`
813    pub fn sof_zman_tefila_mga_16_1_degrees(&self) -> Option<DateTime<Tz>> {
814        Some(zmanim_calculator::sof_zman_tefila(
815            &self.alos_16_1_degrees()?,
816            &self.tzais_16_1_degrees()?,
817        ))
818    }
819
820    /// This method returns the latest time for burning *chametz* on *Erev
821    /// Pesach* according to the opinion of the *Magen Avraham* (MGA) based on
822    /// *alos* being 16.1&deg; before sunrise. This time is 5 *shaos zmaniyos*
823    /// (temporal hours) after dawn based on the opinion of the MGA that the day
824    /// is calculated from dawn to nightfall with both being 16.1&deg; below
825    /// sunrise or sunset. Since this library does not implement a calendar,
826    /// this method will return the *zman* any day of the year.
827    pub fn sof_zman_biur_chametz_mga_16_1_degrees(&self) -> Option<DateTime<Tz>> {
828        Some(self.alos_16_1_degrees()? + (self.shaah_zmanis_16_1_degrees()? * 5))
829    }
830
831    /// Returns the time of *mincha gedola* according to the *Magen
832    /// Avraham* with the day starting and ending 16.1&deg; below the horizon.
833    /// This is the earliest time to pray *mincha*. For more information on
834    /// this see the documentation on [*mincha
835    /// gedola*](zmanim_calculator::mincha_gedola). This is calculated as
836    /// 6.5 solar hours after *alos*. The calculation used is `self.
837    /// alos_16_1_degrees()? + (self.shaah_zmanis_16_1_degrees()? * 6.5)`
838    pub fn mincha_gedola_mga_16_1_degrees(&self) -> Option<DateTime<Tz>> {
839        Some(zmanim_calculator::mincha_gedola(
840            &self.alos_16_1_degrees()?,
841            &self.tzais_16_1_degrees()?,
842        ))
843    }
844
845    /// A method for calculating *samuch lemincha ketana*, / near *mincha
846    /// ketana* time that is half an hour before [*mincha
847    /// ketana*](ComplexZmanimCalendar::mincha_ketana_mga_16_1_degrees) or is 9
848    /// *shaos zmaniyos* (solar hours) after the start of the day, calculated
849    /// using a day starting and ending 16.1&deg; below the horizon. This is
850    /// the time that eating or other activity can't begin prior to praying
851    /// *mincha*. See the *Mechaber* and *Mishna Berurah* 232 and 249:2.
852    pub fn samuch_lemincha_ketana_mga_16_1_degrees(&self) -> Option<DateTime<Tz>> {
853        Some(self.alos_16_1_degrees()? + (self.shaah_zmanis_16_1_degrees()? * 9))
854    }
855
856    /// Returns the time of *mincha ketana* according to the *Magen
857    /// Avraham* with the day starting and ending 16.1&deg; below the horizon.
858    /// This is the preferred earliest time to pray *mincha* according to
859    /// the opinion of the *Rambam* and others. For more information on this
860    /// see the documentation on [*mincha
861    /// gedola*](zmanim_calculator::mincha_gedola). This is calculated as
862    /// 9.5 solar hours after *alos*. The calculation used
863    /// is `self.alos_16_1_degrees()? + (self.shaah_zmanis_16_1_degrees()? *
864    /// 9.5)`
865    pub fn mincha_ketana_mga_16_1_degrees(&self) -> Option<DateTime<Tz>> {
866        Some(zmanim_calculator::mincha_ketana(
867            &self.alos_16_1_degrees()?,
868            &self.tzais_16_1_degrees()?,
869        ))
870    }
871
872    /// This method should be used *lechumra* only and returns the time of *plag
873    /// hamincha* based on the opinion that the day starts at *alos* 16.1&deg;
874    /// and ends at *tzais* 16.1&deg;. This is calculated as 10.75 hours
875    /// *zmaniyos* after dawn. The formula used is
876    /// `self.alos_16_1_degrees()? + (self.shaah_zmanis_16_1_degrees()? *
877    /// 10.75)`. Since plag by this calculation can occur after sunset, it
878    /// should only be used *lechumra*.
879    pub fn plag_mga_16_1_degrees(&self) -> Option<DateTime<Tz>> {
880        Some(zmanim_calculator::plag_hamincha(
881            &self.alos_16_1_degrees()?,
882            &self.tzais_16_1_degrees()?,
883        ))
884    }
885
886    /// For information on how this is calculated see the documentation on
887    /// [alos_16_1_degrees](ComplexZmanimCalendar::alos_16_1_degrees)
888    pub fn tzais_16_1_degrees(&self) -> Option<DateTime<Tz>> {
889        self.tzais(&Degrees(16.1))
890    }
891
892    /// Returns a *shaah zmanis* (temporal hour) calculated using a 16.1&deg;
893    /// dip. This calculation divides the day based on the opinion of the
894    /// *Magen Avraham* (MGA) that the day runs from dawn to dusk. Dawn for
895    /// this calculation is when the sun is 16.1&deg; below the eastern
896    /// geometric horizon before sunrise. Dusk for this is when the sun is
897    /// 16.1&deg; below the western geometric horizon after sunset. This day
898    /// is split into 12 equal parts with each part being a *shaah zmanis*.
899    pub fn shaah_zmanis_16_1_degrees(&self) -> Option<TimeDelta> {
900        Some(zmanim_calculator::shaah_zmanis(
901            &self.alos_16_1_degrees()?,
902            &self.tzais_16_1_degrees()?,
903        ))
904    }
905
906    // *alos*16.1 degrees to sunset
907    /// Returns the latest *zman krias shema* (time to recite
908    /// *Shema* in the morning) based on the opinion that the day starts at
909    /// *alos* 16.1&deg; and ends at sea level sunset. This is the opinion
910    /// of the *Chidushei UKlalos HaRazah* and the *Menora Hatehora* as
911    /// mentioned by *Yisrael Vehazmanim* vol 1, sec. 7, ch. 3 no. 16. Three
912    /// *shaos zmaniyos* are calculated based on this day and
913    /// added to *alos* to reach this time. This time is 3 *shaos zmaniyos*
914    /// (solar hours) after dawn based on the opinion that the day is
915    /// calculated from a *alos* 16.1&deg; to sea level sunset.
916    pub fn sof_zman_shema_alos_16_1_degrees_to_sunset(&self) -> Option<DateTime<Tz>> {
917        Some(zmanim_calculator::sof_zman_shema(
918            &self.alos_16_1_degrees()?,
919            &self.shkia()?,
920        ))
921    }
922
923    /// This method should be used *lechumra* only and returns the time of *plag
924    /// hamincha* based on the opinion that the day starts at *alos* 16.1&deg;
925    /// and ends at sunset. 10.75 *shaos zmaniyos* are calculated based on
926    /// this day and added to *alos*to reach this time. This time is 10.75
927    /// *shaos zmaniyos* (temporal hours) after dawn based on the opinion
928    /// that the day is calculated from a dawn of 16.1 degrees before
929    /// sunrise to sunset. This returns the time of 10.75 * the calculated
930    /// *shaah zmanis* after dawn. Since plag by this calculation can occur
931    /// after sunset, it should only be used *lechumra*.
932    pub fn plag_alos_16_1_degrees_to_sunset(&self) -> Option<DateTime<Tz>> {
933        Some(zmanim_calculator::plag_hamincha(
934            &self.alos_16_1_degrees()?,
935            &self.shkia()?,
936        ))
937    }
938
939    // 16.1 degrees to *tzais* geonim 7.083 degrees
940    /// Returns the latest *zman krias shema* (time to recite
941    /// *Shema* in the morning) based on the opinion that the day starts at
942    /// *alos* 16.1&deg; and ends at *tzais* 7.083&deg;. 3 *shaos zmaniyos*
943    /// are calculated based on this day and added to *alos*to reach this
944    /// time. This time is 3 *shaos zmaniyos* (temporal hours) after alos
945    /// 16.1&deg; based on the opinion that the day is calculated from a
946    /// *alos* 16.1&deg; to *tzais* 7.083&deg;.
947    pub fn sof_zman_shema_alos_16_1_degrees_to_tzais_geonim_7_083_degrees(
948        &self,
949    ) -> Option<DateTime<Tz>> {
950        Some(zmanim_calculator::sof_zman_shema(
951            &self.alos_16_1_degrees()?,
952            &self.tzais_geonim_7_083_degrees()?,
953        ))
954    }
955
956    /// Returns the time of *plag hamincha* based on the opinion
957    /// that the day starts at *alos* 16.1&deg; and ends at *tzais*
958    /// 7.083&deg;. 10.75 *shaos zmaniyos* are calculated based on this day
959    /// and added to *alos* to reach this time. This time is 10.75 *shaos
960    /// zmaniyos* (temporal hours) after dawn based on the opinion that the
961    /// day is calculated from a dawn of 16.1 degrees before sunrise to
962    /// *tzais* 7.083&deg;. This returns the time of 10.75 * the calculated
963    /// *shaah zmanis* after dawn.
964    pub fn plag_alos_16_1_degrees_to_tzais_geonim_7_083_degrees(&self) -> Option<DateTime<Tz>> {
965        Some(zmanim_calculator::plag_hamincha(
966            &self.alos_16_1_degrees()?,
967            &self.tzais_geonim_7_083_degrees()?,
968        ))
969    }
970
971    // 18 degrees
972    /// A method to return *alos* (dawn) calculated when the sun is 18&deg;
973    /// below the eastern geometric horizon before sunrise.
974    pub fn alos_18_degrees(&self) -> Option<DateTime<Tz>> {
975        self.alos(&Degrees(18.0))
976    }
977
978    /// Returns the latest *zman krias shema* (time to recite
979    /// *Shema* in the morning) according to the opinion of the *Magen
980    /// Avraham* (MGA) based on *alos* being 18&deg; before sunrise. This time
981    /// is 3 *shaos zmaniyos* (solar hours) after dawn based on the opinion
982    /// of the MGA that the day is calculated from dawn to nightfall with
983    /// both being 18&deg; below sunrise or sunset. This returns the time of
984    /// `self.alos_18_degrees()? + (self.shaah_zmanis_18_degrees()? * 3.0)`
985    pub fn sof_zman_shema_mga_18_degrees(&self) -> Option<DateTime<Tz>> {
986        Some(zmanim_calculator::sof_zman_shema(
987            &self.alos_18_degrees()?,
988            &self.tzais_18_degrees()?,
989        ))
990    }
991
992    /// Returns the latest *zman tefila* (time to recite the morning
993    /// prayers) according to the opinion of the *Magen Avraham* (MGA) based on
994    /// *alos*being 18&deg; before sunrise. This time is 4 *shaos zmaniyos*
995    /// (solar hours) after dawn based on the opinion of the MGA that the
996    /// day is calculated from dawn to nightfall with both being 18&deg;
997    /// below sunrise or sunset. This returns the time of
998    /// `self.alos_18_degrees()? + (self.shaah_zmanis_18_degrees()? * 4.0)`
999    pub fn sof_zman_tefila_mga_18_degrees(&self) -> Option<DateTime<Tz>> {
1000        Some(zmanim_calculator::sof_zman_tefila(
1001            &self.alos_18_degrees()?,
1002            &self.tzais_18_degrees()?,
1003        ))
1004    }
1005
1006    /// This method should be used *lechumra* only and returns the time of *plag
1007    /// hamincha* based on the opinion that the day starts at *alos* 18&deg; and
1008    /// ends at *tzais* 18&deg;. This is calculated as 10.75 hours *zmaniyos*
1009    /// after dawn. The formula used is `self.alos_18_degrees()? +
1010    /// (self.shaah_zmanis_18_degrees()? * 10.75)`. Since plag by this
1011    /// calculation can occur after sunset, it should only be used
1012    /// *lechumra*.
1013    pub fn plag_mga_18_degrees(&self) -> Option<DateTime<Tz>> {
1014        Some(zmanim_calculator::plag_hamincha(
1015            &self.alos_18_degrees()?,
1016            &self.tzais_18_degrees()?,
1017        ))
1018    }
1019
1020    /// For information on how this is calculated see the documentation on
1021    /// [alos_18_degrees](ComplexZmanimCalendar::alos_18_degrees)
1022    pub fn tzais_18_degrees(&self) -> Option<DateTime<Tz>> {
1023        self.tzais(&Degrees(18.0))
1024    }
1025
1026    /// Returns a *shaah zmanis* (temporal hour) calculated using a 18&deg; dip.
1027    /// This calculation divides the day based on the opinion of the *Magen
1028    /// Avraham* (MGA) that the day runs from dawn to dusk. Dawn for this
1029    /// calculation is when the sun is 18&deg; below the eastern geometric
1030    /// horizon before sunrise. Dusk for this is when the sun is 18&deg; below
1031    /// the western geometric horizon after sunset. This day is split into 12
1032    /// equal parts with each part being a *shaah zmanis*.
1033    pub fn shaah_zmanis_18_degrees(&self) -> Option<TimeDelta> {
1034        Some(zmanim_calculator::shaah_zmanis(
1035            &self.alos_18_degrees()?,
1036            &self.tzais_18_degrees()?,
1037        ))
1038    }
1039
1040    // 19 degrees
1041    /// A method to return *alos* (dawn) calculated when the sun is 19&deg;
1042    /// below the eastern geometric horizon before sunrise. This is the
1043    /// *Rambam*'s *alos* according to Rabbi Moshe Kosower's *Maaglei
1044    /// Tzedek*, page 88, *Ayeles Hashachar* Vol. I, page 12, *Yom Valayla
1045    /// Shel Torah*, Ch. 34, p. 222 and Rabbi Yaakov Shakow's *Luach Ikvei
1046    /// Hayom*.
1047    pub fn alos_19_degrees(&self) -> Option<DateTime<Tz>> {
1048        self.alos(&Degrees(19.0))
1049    }
1050
1051    // 19.8 degrees
1052    /// Returns *alos* (dawn) calculated when the sun is 19.8&deg;
1053    /// below the eastern geometric horizon before sunrise. This calculation
1054    /// is based on the same calculation of 90 minutes but uses a
1055    /// degree-based calculation instead of 90 exact minutes. This
1056    /// calculation is based on the position of the sun 90 minutes before
1057    /// sunrise in Jerusalem around the equinox / equilux, which calculates
1058    /// to 19.8&deg; below geometric zenith.
1059    pub fn alos_19_8_degrees(&self) -> Option<DateTime<Tz>> {
1060        self.alos(&Degrees(19.8))
1061    }
1062
1063    /// Returns the latest *zman krias shema* (time to recite
1064    /// *Shema* in the morning) according to the opinion of the *Magen
1065    /// Avraham* (MGA) based on *alos* being 19.8&deg; before sunrise. This time
1066    /// is 3 *shaos zmaniyos* (solar hours) after dawn based on the opinion
1067    /// of the MGA that the day is calculated from dawn to nightfall with
1068    /// both being 19.8&deg; below sunrise or sunset. This returns the time of
1069    /// `self.alos_19_8_degrees()? + (self.shaah_zmanis_19_8_degrees()? * 3.0)`
1070    pub fn sof_zman_shema_mga_19_8_degrees(&self) -> Option<DateTime<Tz>> {
1071        Some(zmanim_calculator::sof_zman_shema(
1072            &self.alos_19_8_degrees()?,
1073            &self.tzais_19_8_degrees()?,
1074        ))
1075    }
1076
1077    /// Returns the latest *zman tefila* (time to recite the morning
1078    /// prayers) according to the opinion of the *Magen Avraham* (MGA) based on
1079    /// *alos*being 19.8&deg; before sunrise. This time is 4 *shaos zmaniyos*
1080    /// (solar hours) after dawn based on the opinion of the MGA that the
1081    /// day is calculated from dawn to nightfall with both being 19.8&deg;
1082    /// below sunrise or sunset. This returns the time of
1083    /// `self.alos_19_8_degrees()? + (self.shaah_zmanis_19_8_degrees()? *
1084    /// 4.0)`
1085    pub fn sof_zman_tefila_mga_19_8_degrees(&self) -> Option<DateTime<Tz>> {
1086        Some(zmanim_calculator::sof_zman_tefila(
1087            &self.alos_19_8_degrees()?,
1088            &self.tzais_19_8_degrees()?,
1089        ))
1090    }
1091
1092    /// This method should be used *lechumra* only and returns the time of *plag
1093    /// hamincha* based on the opinion that the day starts at *alos* 19.8&deg;
1094    /// and ends at *tzais* 19.8&deg;. This is calculated as 10.75 hours
1095    /// *zmaniyos* after dawn. The formula used is
1096    /// `self.alos_19_8_degrees()? + (self.shaah_zmanis_19_8_degrees()? *
1097    /// 10.75)`. Since plag by this calculation can occur after sunset, it
1098    /// should only be used *lechumra*.
1099    pub fn plag_mga_19_8_degrees(&self) -> Option<DateTime<Tz>> {
1100        Some(zmanim_calculator::plag_hamincha(
1101            &self.alos_19_8_degrees()?,
1102            &self.tzais_19_8_degrees()?,
1103        ))
1104    }
1105
1106    /// For information on how this is calculated see the documentation on
1107    /// [alos_19_8_degrees](ComplexZmanimCalendar::alos_19_8_degrees)
1108    pub fn tzais_19_8_degrees(&self) -> Option<DateTime<Tz>> {
1109        self.tzais(&Degrees(19.8))
1110    }
1111
1112    /// Returns a *shaah zmanis* (temporal hour) calculated using a 19.8&deg;
1113    /// dip. This calculation divides the day based on the opinion of the
1114    /// *Magen Avraham* (MGA) that the day runs from dawn to dusk. Dawn for
1115    /// this calculation is when the sun is 19.8&deg; below the eastern
1116    /// geometric horizon before sunrise. Dusk for this is when the sun is
1117    /// 19.8&deg; below the western geometric horizon after sunset. This day
1118    /// is split into 12 equal parts with each part being a *shaah zmanis*.
1119    pub fn shaah_zmanis_19_8_degrees(&self) -> Option<TimeDelta> {
1120        Some(zmanim_calculator::shaah_zmanis(
1121            &self.alos_19_8_degrees()?,
1122            &self.tzais_19_8_degrees()?,
1123        ))
1124    }
1125
1126    // 26 degrees
1127    /// This method should be used *lechumra* only and returns *alos* (dawn)
1128    /// calculated when the sun is 26&deg; below the eastern geometric horizon
1129    /// before sunrise. This calculation is based on the same calculation of 120
1130    /// minutes but uses a degree-based calculation instead of 120 exact
1131    /// minutes. This calculation is based on the position of the sun 120
1132    /// minutes before sunrise in Jerusalem around the equinox / equilux, which
1133    /// calculates to 26&deg; below geometric zenith. Since this time is
1134    /// extremely early, it should only be used *lechumra* only, such as not
1135    /// eating after this time on a fast day, and not as the start time for
1136    /// *mitzvos* that can only be performed during the day.
1137    pub fn alos_26_degrees(&self) -> Option<DateTime<Tz>> {
1138        self.alos(&Degrees(26.0))
1139    }
1140
1141    /// This method should be used *lechumra* only and returns the time of *plag
1142    /// hamincha* based on the opinion that the day starts at *alos* 26&deg; and
1143    /// ends at *tzais* 26&deg;. This is calculated as 10.75 hours *zmaniyos*
1144    /// after dawn. The formula used is `self.alos_26_degrees()? +
1145    /// (self.shaah_zmanis_26_degrees()? * 10.75)`. Since plag by this
1146    /// calculation can occur after sunset, it should only be used
1147    /// *lechumra*.
1148    pub fn plag_mga_26_degrees(&self) -> Option<DateTime<Tz>> {
1149        Some(zmanim_calculator::plag_hamincha(
1150            &self.alos_26_degrees()?,
1151            &self.tzais_26_degrees()?,
1152        ))
1153    }
1154
1155    /// For information on how this is calculated see the documentation on
1156    /// [alos_26_degrees](ComplexZmanimCalendar::alos_26_degrees)
1157    pub fn tzais_26_degrees(&self) -> Option<DateTime<Tz>> {
1158        self.tzais(&Degrees(26.0))
1159    }
1160
1161    /// Returns a *shaah zmanis* (temporal hour) calculated using a 26&deg; dip.
1162    /// This calculation divides the day based on the opinion of the *Magen
1163    /// Avraham* (MGA) that the day runs from dawn to dusk. Dawn for this
1164    /// calculation is when the sun is 26&deg; below the eastern geometric
1165    /// horizon before sunrise. Dusk for this is when the sun is 26&deg; below
1166    /// the western geometric horizon after sunset. This day is split into 12
1167    /// equal parts with each part being a *shaah zmanis*. Since *zmanim* that
1168    /// use this method are extremely late or early and at a point when the sky
1169    /// is a long time past the 18&deg; point where the darkest point is
1170    /// reached, *zmanim* that use this should only be used *lechumra*, such as
1171    /// delaying the start of nighttime *mitzvos*.
1172    pub fn shaah_zmanis_26_degrees(&self) -> Option<TimeDelta> {
1173        Some(zmanim_calculator::shaah_zmanis(
1174            &self.alos_26_degrees()?,
1175            &self.tzais_26_degrees()?,
1176        ))
1177    }
1178
1179    // 60 minutes
1180    /// Returns *alos* (dawn) calculated as 60 minutes before sunrise
1181    /// or sea level sunrise (depending on `use_elevation`). This is the
1182    /// time to walk the distance of 4 *mil* at 15 minutes a *mil*. This
1183    /// seems to be the opinion of the *Chavas Yair* in the *Mekor Chaim,
1184    /// Orach Chaim* Ch. 90, though the *Mekor Chaim* in Ch. 58 and in the *Chut
1185    /// Hashani* Ch. 97 states that a person walks 3 and a 1/3 *mil* in an hour,
1186    /// or an 18-minute *mil*. Also see the *Divrei Malkiel* Vol. 4, Ch. 20,
1187    /// page 34) who mentions the 15 minute *mil lechumra* by baking
1188    /// *matzos*. Also see the *Maharik* Ch. 173 where the questioner
1189    /// quoting the *Ra'avan* is of the opinion that the time to walk a
1190    /// *mil* is 15 minutes (5 *mil* in a little over an hour). There are
1191    /// many who believe that there is a *ta'us sofer* (scribeal error) in
1192    /// the *Ra'avan*, and it should 4 *mil* in a little over an hour, or an
1193    /// 18-minute *mil*. Time based offset calculations are based on
1194    /// the opinion of the *Rishonim* who stated that the time of the *neshef*
1195    /// (time between dawn and sunrise) does not vary by the time of year or
1196    /// location but purely depends on the time it takes to walk the
1197    /// distance of 4 *mil*.
1198    pub fn alos_60_minutes(&self) -> Option<DateTime<Tz>> {
1199        self.alos(&Minutes(60.0))
1200    }
1201
1202    /// Returns the time of *plag hamincha* according to the *Magen
1203    /// Avraham* with the day starting 60 minutes before sunrise and ending 60
1204    /// minutes after sunset. This is calculated as 10.75 hours after dawn. The
1205    /// formula used is `self.alos_60_minutes()? +
1206    /// (self.shaah_zmanis_60_minutes()? * 10.75)`
1207    pub fn plag_mga_60_minutes(&self) -> Option<DateTime<Tz>> {
1208        Some(zmanim_calculator::plag_hamincha(
1209            &self.alos_60_minutes()?,
1210            &self.tzais_60_minutes()?,
1211        ))
1212    }
1213
1214    /// Returns *tzais hakochavim* (nightfall) based on the opinion
1215    /// of the *Chavas Yair* and *Divrei Malkiel* that the time to walk the
1216    /// distance of a mil is 15 minutes, for a total of 60 minutes for 4
1217    /// *mil* after sea level sunset. See detailed documentation explaining
1218    /// the 60 minute concept at
1219    /// [alos_60_minutes](ComplexZmanimCalendar::alos_60_minutes).
1220    pub fn tzais_60_minutes(&self) -> Option<DateTime<Tz>> {
1221        self.tzais(&Minutes(60.0))
1222    }
1223
1224    /// Returns a *shaah zmanis* (solar hour) according to the opinion
1225    /// of the *Magen Avraham* (MGA). This calculation divides the day based on
1226    /// the opinion of the MGA that the day runs from dawn to dusk. Dawn for
1227    /// this calculation is 60 minutes before sunrise and dusk is 60 minutes
1228    /// after sunset. This day is split into 12 equal parts with each part being
1229    /// a *shaah zmanis*.
1230    pub fn shaah_zmanis_60_minutes(&self) -> Option<TimeDelta> {
1231        Some(zmanim_calculator::shaah_zmanis(
1232            &self.alos_60_minutes()?,
1233            &self.tzais_60_minutes()?,
1234        ))
1235    }
1236
1237    // 72 minutes
1238    /// Return *alos* (dawn) calculated as 72 minutes before
1239    /// [sunrise](crate::astronomical_calculator::sunrise) or [sea level
1240    /// sunrise](crate::astronomical_calculator::sea_level_sunrise) (depending
1241    /// on `use_elevation`). This time is based on the time to walk the distance
1242    /// of 4 *mil* at 18 minutes per *mil*. The 72-minute time (but not the
1243    /// concept of fixed minutes) is based on the opinion that the time of the
1244    /// *Neshef* (twilight between dawn and sunrise) does not vary by the time
1245    /// of year or location but depends on the time it takes to walk the
1246    /// distance of 4 mil
1247    pub fn alos_72_minutes(&self) -> Option<DateTime<Tz>> {
1248        self.alos(&Minutes(72.0))
1249    }
1250
1251    /// Returns the latest *zman krias shema* (time to recite
1252    /// *Shema* in the morning) according to the opinion of the *Magen
1253    /// Avraham* (MGA) based on *alos*being 72 minutes before sunrise. This
1254    /// time is 3 *shaos zmaniyos* (solar hours) after dawn based on the
1255    /// opinion of the MGA that the day is calculated from a dawn of 72
1256    /// minutes before sunrise to nightfall of 72 minutes after sunset. This
1257    /// Returns the time of `self.alos_72_minutes() +
1258    /// (self.shaah_zmanis_72_minutes()? * 3.0)`
1259    pub fn sof_zman_shema_mga_72_minutes(&self) -> Option<DateTime<Tz>> {
1260        Some(zmanim_calculator::sof_zman_shema(
1261            &self.alos_72_minutes()?,
1262            &self.tzais_72_minutes()?,
1263        ))
1264    }
1265
1266    /// Returns the latest *zman tefila* (time to recite the morning
1267    /// prayers) according to the opinion of the *Magen Avraham* (MGA) based on
1268    /// *alos*being 72 minutes before sunrise. This time is 4 *shaos zmaniyos*
1269    /// (solar hours) after dawn based on the opinion of the MGA that the day is
1270    /// calculated from a dawn of 72 minutes before sunrise to nightfall of 72
1271    /// minutes after sunset. This returns the time of
1272    /// `self.alos_72_minutes()? + (self.shaah_zmanis_72_minutes()? * 4.0)`
1273    pub fn sof_zman_tefila_mga_72_minutes(&self) -> Option<DateTime<Tz>> {
1274        Some(zmanim_calculator::sof_zman_tefila(
1275            &self.alos_72_minutes()?,
1276            &self.tzais_72_minutes()?,
1277        ))
1278    }
1279
1280    /// This method returns the latest time for burning *chametz* on *Erev
1281    /// Pesach* according to the opinion of the *Magen Avraham* (MGA) based on
1282    /// *alos* being 72 minutes before sunrise. This time is 5 *shaos zmaniyos*
1283    /// (temporal hours) after dawn based on the opinion of the MGA that the day
1284    /// is calculated from a dawn of 72 minutes before sunrise to nightfall of
1285    /// 72 minutes after sunset. Since this library does not implement a
1286    /// calendar, this method will return the *zman* any day of the year.
1287    pub fn sof_zman_biur_chametz_mga_72_minutes(&self) -> Option<DateTime<Tz>> {
1288        Some(self.alos_72_minutes()? + (self.shaah_zmanis_72_minutes()? * 5))
1289    }
1290
1291    /// Returns the time of *mincha gedola* according to the *Magen
1292    /// Avraham* with the day starting 72 minutes before sunrise and ending 72
1293    /// minutes after sunset. This is the earliest time to pray *mincha*. For
1294    /// more information on this see the documentation on [*mincha
1295    /// gedola*](zmanim_calculator::mincha_gedola). This is calculated as
1296    /// 6.5 solar hours after *alos*. The calculation used is `self.
1297    /// alos_72_minutes()? + (self.shaah_zmanis_72_minutes()? * 6.5)`
1298    pub fn mincha_gedola_mga_72_minutes(&self) -> Option<DateTime<Tz>> {
1299        Some(zmanim_calculator::mincha_gedola(
1300            &self.alos_72_minutes()?,
1301            &self.tzais_72_minutes()?,
1302        ))
1303    }
1304
1305    /// A method for calculating *samuch lemincha ketana*, / near *mincha
1306    /// ketana* time that is half an hour before [*mincha
1307    /// ketana*](ComplexZmanimCalendar::mincha_ketana_mga_72_minutes) or is 9
1308    /// *shaos zmaniyos* (solar hours) after the start of the day, calculated
1309    /// using a day starting 72 minutes before sunrise and ending 72 minutes
1310    /// after sunset. This is the time that eating or other activity can't begin
1311    /// prior to praying *mincha*. See the *Mechaber* and *Mishna Berurah* 232
1312    /// and 249:2.
1313    pub fn samuch_lemincha_ketana_mga_72_minutes(&self) -> Option<DateTime<Tz>> {
1314        Some(self.alos_72_minutes()? + (self.shaah_zmanis_72_minutes()? * 9))
1315    }
1316
1317    /// Returns the time of *mincha ketana* according to the *Magen
1318    /// Avraham* with the day starting 72 minutes before sunrise and ending 72
1319    /// minutes after sunset. This is the preferred earliest time to pray
1320    /// *mincha* according to the opinion of the *Rambam* and others. For
1321    /// more information on this see the documentation on [*mincha
1322    /// gedola*](zmanim_calculator::mincha_gedola). This is calculated as
1323    /// `self.alos_72_minutes()? + (self.shaah_zmanis_72_minutes()? * 9.5)`
1324    pub fn mincha_ketana_mga_72_minutes(&self) -> Option<DateTime<Tz>> {
1325        Some(zmanim_calculator::mincha_ketana(
1326            &self.alos_72_minutes()?,
1327            &self.tzais_72_minutes()?,
1328        ))
1329    }
1330
1331    /// Returns the time of *plag hamincha* according to the *Magen
1332    /// Avraham* with the day starting 72 minutes before sunrise and ending 72
1333    /// minutes after sunset. This is calculated as 10.75 hours after dawn. The
1334    /// formula used is `self.alos_72_minutes()? +
1335    /// (self.shaah_zmanis_72_minutes()? * 10.75)`. Since *plag* by this
1336    /// calculation can occur after sunset, it should only be used *lechumra*.
1337    pub fn plag_mga_72_minutes(&self) -> Option<DateTime<Tz>> {
1338        Some(zmanim_calculator::plag_hamincha(
1339            &self.alos_72_minutes()?,
1340            &self.tzais_72_minutes()?,
1341        ))
1342    }
1343
1344    /// Returns *tzais hakochavim* (nightfall) based on the opinion
1345    /// of *Rabbeinu Tam* that *tzais hakochavim* is calculated as 72
1346    /// minutes after sunset, the time it takes to walk 4 *mil* at 18
1347    /// minutes a mil. According to the *Machtzis Hashekel* in *Orach Chaim*
1348    /// 235:3, the *Pri Megadim* in *Orach Chaim* 261:2 (see the *Biur
1349    /// Halacha*) and others (see *Hazmanim Bahalacha* 17:3 and 17:5) the 72
1350    /// minutes are standard clock minutes any time of the year in any
1351    /// location.
1352    pub fn tzais_72_minutes(&self) -> Option<DateTime<Tz>> {
1353        self.tzais(&Minutes(72.0))
1354    }
1355
1356    /// Returns a *shaah zmanis* (solar hour) according to the opinion
1357    /// of the *Magen Avraham* (MGA). This calculation divides the day based on
1358    /// the opinion of the MGA that the day runs from dawn to dusk. Dawn for
1359    /// this calculation is 72 minutes before sunrise and dusk is 72 minutes
1360    /// after sunset. This day is split into 12 equal parts with each part being
1361    /// a *shaah zmanis*.
1362    pub fn shaah_zmanis_72_minutes(&self) -> Option<TimeDelta> {
1363        Some(zmanim_calculator::shaah_zmanis(
1364            &self.alos_72_minutes()?,
1365            &self.tzais_72_minutes()?,
1366        ))
1367    }
1368
1369    // 72 minutes zmanis
1370    /// Returns *alos* (dawn) calculated using 72 minutes *zmaniyos* or
1371    /// 1/10th of the day before sunrise. This is based on an 18-minute *mil* so
1372    /// the time for 4 *mil* is 72 minutes which is 1/10th of a day `12 * 60 =
1373    /// 720` based on the day being from sea level sunrise to sea level sunset
1374    /// or sunrise to sunset (depending on `use_elevation`). The actual
1375    /// calculation is `astronomical_calculator::sea_level_sunrise(&self.
1376    /// date, &self.geo_location) - (&self.shaah_zmanis_gra()? * 1.2)`. This
1377    /// calculation is used in the calendars published by the Hisachdus
1378    /// Harabanim D'Artzos Habris Ve'Canada.
1379    pub fn alos_72_minutes_zmanis(&self) -> Option<DateTime<Tz>> {
1380        self.alos(&MinutesZmaniyos {
1381            minutes_zmaniyos: 72.0,
1382            shaah_zmanis: &self.shaah_zmanis_gra()?,
1383        })
1384    }
1385
1386    /// Returns the latest *zman krias shema* (time to recite
1387    /// *Shema* in the morning) according to the opinion of the *Magen
1388    /// Avraham* (MGA) based on *alos* being 72 minutes *zmaniyos*, or
1389    /// 1/10th of the day before sunrise. This time is 3 *shaos zmaniyos*
1390    /// (solar hours) after dawn based on the opinion of the MGA that the
1391    /// day is calculated from a dawn of 72 minutes *zmaniyos*, or 1/10th of
1392    /// the day before sea level sunrise to nightfall of 72 minutes
1393    /// *zmaniyos* after sea level sunset. This returns the time of
1394    /// `self.alos_72_minutes_zmanis()? +
1395    /// (self.shaah_zmanis_72_minutes_zmanis()? * 3.0)`
1396    pub fn sof_zman_shema_mga_72_minutes_zmanis(&self) -> Option<DateTime<Tz>> {
1397        Some(zmanim_calculator::sof_zman_shema(
1398            &self.alos_72_minutes_zmanis()?,
1399            &self.tzais_72_minutes_zmanis()?,
1400        ))
1401    }
1402
1403    /// Returns the latest *zman tefila* (time to recite the morning
1404    /// prayers) according to the opinion of the *Magen Avraham* (MGA) based on
1405    /// *alos*being 72 minutes *zmaniyos* before sunrise. This time is 4 *shaos
1406    /// zmaniyos* (solar hours) after dawn based on the opinion of the MGA
1407    /// that the day is calculated from a dawn of 72 minutes *zmaniyos*
1408    /// before sunrise to nightfall of 72 minutes *zmaniyos* after sunset.
1409    /// This returns the time of
1410    /// `self.alos_72_minutes_zmanis()? +
1411    /// (self.shaah_zmanis_72_minutes_zmanis()? * 4.0)`
1412    pub fn sof_zman_tefila_mga_72_minutes_zmanis(&self) -> Option<DateTime<Tz>> {
1413        Some(zmanim_calculator::sof_zman_tefila(
1414            &self.alos_72_minutes_zmanis()?,
1415            &self.tzais_72_minutes_zmanis()?,
1416        ))
1417    }
1418
1419    /// This method returns the latest time for burning *chametz* on *Erev
1420    /// Pesach* according to the opinion of the *Magen Avraham* (MGA) based on
1421    /// *alos* being 72 minutes *zmanis* before sunrise. This time is 5 *shaos
1422    /// zmaniyos* (temporal hours) after dawn based on the opinion of the MGA
1423    /// that the day is calculated from a dawn of 72 minutes *zmanis* before
1424    /// sunrise to nightfall of 72 minutes *zmanis* after sunset. Since this
1425    /// library does not implement a calendar, this method will return the
1426    /// *zman* any day of the year.
1427    pub fn sof_zman_biur_chametz_mga_72_minutes_zmanis(&self) -> Option<DateTime<Tz>> {
1428        Some(self.alos_72_minutes_zmanis()? + (self.shaah_zmanis_72_minutes_zmanis()? * 5))
1429    }
1430
1431    /// Returns the time of *plag hamincha* according to the *Magen
1432    /// Avraham* with the day starting 72 minutes *zmaniyos* before sunrise and
1433    /// ending 72 minutes *zmaniyos* after sunset. This is calculated as
1434    /// 10.75 hours after dawn. The formula used is
1435    /// `self.alos_72_minutes_zmanis()? +
1436    /// (self.shaah_zmanis_72_minutes_zmanis()? * 10.75)`. Since *plag* by this
1437    /// calculation can occur after sunset, it should only be used *lechumra*.
1438    pub fn plag_mga_72_minutes_zmanis(&self) -> Option<DateTime<Tz>> {
1439        Some(zmanim_calculator::plag_hamincha(
1440            &self.alos_72_minutes_zmanis()?,
1441            &self.tzais_72_minutes_zmanis()?,
1442        ))
1443    }
1444
1445    /// Returns *tzais hakochavim* (nightfall) calculated as 72 minutes
1446    /// *zmaniyos*, or 1/10th of the day after sea level sunset. This is the
1447    /// way that the *Minchas Cohen* in *Ma'amar* 2:4 calculates *Rebbeinu
1448    /// Tam*'s time of *tzeis*. It should be noted that this calculation
1449    /// results in the shortest time from sunset to *tzais* being during the
1450    /// winter solstice, the longest at the summer solstice and 72 clock
1451    /// minutes at the equinox. This does not match reality, since there is
1452    /// no direct relationship between the length of the day and twilight.
1453    /// The shortest twilight is during the equinox, the longest is during
1454    /// the summer solstice, and in the winter with the shortest daylight,
1455    /// the twilight period is longer than during the equinoxes.
1456    pub fn tzais_72_minutes_zmanis(&self) -> Option<DateTime<Tz>> {
1457        self.tzais(&MinutesZmaniyos {
1458            minutes_zmaniyos: 72.0,
1459            shaah_zmanis: &self.shaah_zmanis_gra()?,
1460        })
1461    }
1462
1463    /// Returns a *shaah zmanis* (temporal hour) according to the
1464    /// opinion of the *Magen Avraham* (MGA) based on *alos*being 72 minutes
1465    /// *zmaniyos* before sunrise. This calculation divides the day based on the
1466    /// opinion of the MGA that the day runs from dawn to dusk. Dawn for this
1467    /// calculation is 72 minutes *zmaniyos* before sunrise and dusk is 72
1468    /// minutes *zmaniyos* after sunset. This day is split into 12 equal parts
1469    /// with each part being a *shaah zmanis*. This is identical to 1/10th of
1470    /// the day from sunrise to sunset.
1471    pub fn shaah_zmanis_72_minutes_zmanis(&self) -> Option<TimeDelta> {
1472        Some(zmanim_calculator::shaah_zmanis(
1473            &self.alos_72_minutes_zmanis()?,
1474            &self.tzais_72_minutes_zmanis()?,
1475        ))
1476    }
1477
1478    // 90 minutes
1479    /// Returns *alos* (dawn) calculated using 90 minutes before
1480    /// sunrise or sea level sunrise (depending on `use_elevation`) that is
1481    /// based on the time to walk the distance of 4 *mil* at 22.5 minutes a
1482    /// *mil*. Time based offset calculations for *alos* are based on the
1483    /// opinion of the *Rishonim* who stated that the time of the *Neshef* (time
1484    /// between dawn and sunrise) does not vary by the time of year or location
1485    /// but purely depends on the time it takes to walk the distance of 4 *mil*.
1486    pub fn alos_90_minutes(&self) -> Option<DateTime<Tz>> {
1487        self.alos(&Minutes(90.0))
1488    }
1489
1490    /// Returns the latest *zman krias shema* (time to recite
1491    /// *Shema* in the morning) according to the opinion of the *Magen
1492    /// Avraham* (MGA) based on *alos*being 90 minutes before sunrise. This
1493    /// time is 3 *shaos zmaniyos* (solar hours) after dawn based on the
1494    /// opinion of the MGA that the day is calculated from a dawn of 90
1495    /// minutes before sunrise to nightfall of 90 minutes after sunset. This
1496    /// Returns the time of `self.alos_90_minutes() +
1497    /// (self.shaah_zmanis_90_minutes()? * 3.0)`
1498    pub fn sof_zman_shema_mga_90_minutes(&self) -> Option<DateTime<Tz>> {
1499        Some(zmanim_calculator::sof_zman_shema(
1500            &self.alos_90_minutes()?,
1501            &self.tzais_90_minutes()?,
1502        ))
1503    }
1504
1505    /// Returns the latest *zman tefila* (time to recite the morning
1506    /// prayers) according to the opinion of the *Magen Avraham* (MGA) based on
1507    /// *alos*being 90 minutes before sunrise. This time is 4 *shaos zmaniyos*
1508    /// (solar hours) after dawn based on the opinion of the MGA that the day is
1509    /// calculated from a dawn of 90 minutes before sunrise to nightfall of 90
1510    /// minutes after sunset. This returns the time of
1511    /// `self.alos_90_minutes()? + (self.shaah_zmanis_90_minutes()? * 4.0)`
1512    pub fn sof_zman_tefila_mga_90_minutes(&self) -> Option<DateTime<Tz>> {
1513        Some(zmanim_calculator::sof_zman_tefila(
1514            &self.alos_90_minutes()?,
1515            &self.tzais_90_minutes()?,
1516        ))
1517    }
1518
1519    /// Returns the time of *plag hamincha* according to the *Magen
1520    /// Avraham* with the day starting 90 minutes before sunrise and ending 90
1521    /// minutes after sunset. This is calculated as 10.75 hours after dawn. The
1522    /// formula used is `self.alos_90_minutes()? +
1523    /// (self.shaah_zmanis_90_minutes()? * 10.75)`. Since *plag* by this
1524    /// calculation can occur after sunset, it should only be used *lechumra*.
1525    pub fn plag_mga_90_minutes(&self) -> Option<DateTime<Tz>> {
1526        Some(zmanim_calculator::plag_hamincha(
1527            &self.alos_90_minutes()?,
1528            &self.tzais_90_minutes()?,
1529        ))
1530    }
1531
1532    /// Returns *tzais hakochavim* (dusk) calculated as 90 minutes
1533    /// after sea level sunset. This method returns *tzais* based on the opinion
1534    /// of the *Magen Avraham* that the time to walk the distance of a *mil*
1535    /// according to the *Rambam*'s opinion is 18 minutes, for a total of 90
1536    /// minutes based on the opinion of Ula who calculated *tzais* as 5 *mil*
1537    /// after *shkiah* (sunset). A similar calculation
1538    /// [tzais_19_8_degrees](ComplexZmanimCalendar::tzais_19_8_degrees) uses
1539    /// solar position calculations based on this time.
1540    pub fn tzais_90_minutes(&self) -> Option<DateTime<Tz>> {
1541        self.tzais(&Minutes(90.0))
1542    }
1543
1544    /// Returns a *shaah zmanis* (solar hour) according to the opinion
1545    /// of the *Magen Avraham* (MGA). This calculation divides the day based on
1546    /// the opinion of the MGA that the day runs from dawn to dusk. Dawn for
1547    /// this calculation is 90 minutes before sunrise and dusk is 90 minutes
1548    /// after sunset. This day is split into 12 equal parts with each part being
1549    /// a *shaah zmanis*.
1550    pub fn shaah_zmanis_90_minutes(&self) -> Option<TimeDelta> {
1551        Some(zmanim_calculator::shaah_zmanis(
1552            &self.alos_90_minutes()?,
1553            &self.tzais_90_minutes()?,
1554        ))
1555    }
1556
1557    // 90 minutes zmanis
1558    /// Returns *alos* (dawn) calculated using 96 minutes *zmaniyos*
1559    /// or 1/8th of the day before sunrise or sea level sunrise (depending on
1560    /// `use_elevation`). This is based on a 22.5-minute *mil* so the time for
1561    /// 4 *mil* is 90 minutes which is 1/8th of a day `(12 * 60) / 8 = 90`. The
1562    /// day is calculated from sea level sunrise to sea level
1563    /// sunset or sunrise to sunset (depending on `use_elevation`). The actual
1564    /// calculation used is `astronomical_calculator::sunrise(&self.date,
1565    /// &self.geo_location) - (&self.shaah_zmanis_gra()? * 1.5)`.
1566    pub fn alos_90_minutes_zmanis(&self) -> Option<DateTime<Tz>> {
1567        self.alos(&MinutesZmaniyos {
1568            minutes_zmaniyos: 90.0,
1569            shaah_zmanis: &self.shaah_zmanis_gra()?,
1570        })
1571    }
1572
1573    /// Returns the latest *zman krias shema* (time to recite
1574    /// *Shema* in the morning) according to the opinion of the *Magen
1575    /// Avraham* (MGA) based on *alos* being 90 minutes *zmaniyos* before
1576    /// sunrise. This time is 3 *shaos zmaniyos* (solar hours) after dawn
1577    /// based on the opinion of the MGA that the day is calculated from a
1578    /// dawn of 90 minutes *zmaniyos* before sea level sunrise to nightfall of
1579    /// 90 minutes *zmaniyos* after sea level sunset. This returns the time
1580    /// of `self.alos_90_minutes_zmanis() +
1581    /// (self.shaah_zmanis_90_minutes_zmanis()? * 3.0)`
1582    pub fn sof_zman_shema_mga_90_minutes_zmanis(&self) -> Option<DateTime<Tz>> {
1583        Some(zmanim_calculator::sof_zman_shema(
1584            &self.alos_90_minutes_zmanis()?,
1585            &self.tzais_90_minutes_zmanis()?,
1586        ))
1587    }
1588
1589    /// Returns the latest *zman tefila* (time to recite the morning
1590    /// prayers) according to the opinion of the *Magen Avraham* (MGA) based on
1591    /// *alos*being 90 minutes *zmaniyos* before sunrise. This time is 4 *shaos
1592    /// zmaniyos* (solar hours) after dawn based on the opinion of the MGA
1593    /// that the day is calculated from a dawn of 90 minutes *zmaniyos*
1594    /// before sunrise to nightfall of 90 minutes *zmaniyos* after sunset.
1595    /// This returns the time of
1596    /// `self.alos_90_minutes_zmanis()? +
1597    /// (self.shaah_zmanis_90_minutes_zmanis()? * 4.0)`
1598    pub fn sof_zman_tefila_mga_90_minutes_zmanis(&self) -> Option<DateTime<Tz>> {
1599        Some(zmanim_calculator::sof_zman_tefila(
1600            &self.alos_90_minutes_zmanis()?,
1601            &self.tzais_90_minutes_zmanis()?,
1602        ))
1603    }
1604
1605    /// Returns the time of *plag hamincha* according to the *Magen
1606    /// Avraham* with the day starting 90 minutes *zmaniyos* before sunrise and
1607    /// ending 90 minutes *zmaniyos* after sunset. This is calculated as
1608    /// 10.75 hours after dawn. The formula used is
1609    /// `self.alos_90_minutes_zmanis()? +
1610    /// (self.shaah_zmanis_90_minutes_zmanis()? * 10.75)`. Since *plag* by this
1611    /// calculation can occur after sunset, it should only be used *lechumra*.
1612    pub fn plag_mga_90_minutes_zmanis(&self) -> Option<DateTime<Tz>> {
1613        Some(zmanim_calculator::plag_hamincha(
1614            &self.alos_90_minutes_zmanis()?,
1615            &self.tzais_90_minutes_zmanis()?,
1616        ))
1617    }
1618
1619    /// Returns *tzais hakochavim* (dusk) calculated using 90 minutes
1620    /// *zmaniyos* or 1/8th of the day after sea level sunset. This time is
1621    /// known in Yiddish as the *achtel* (an eighth) *zman*.
1622    pub fn tzais_90_minutes_zmanis(&self) -> Option<DateTime<Tz>> {
1623        self.tzais(&MinutesZmaniyos {
1624            minutes_zmaniyos: 90.0,
1625            shaah_zmanis: &self.shaah_zmanis_gra()?,
1626        })
1627    }
1628
1629    /// Returns a *shaah zmanis** (temporal hour) according to the
1630    /// opinion of the *Magen Avraham* (MGA) based on *alos* being 90 minutes
1631    /// *zmaniyos* before sunrise. This calculation divides the day based on the
1632    /// opinion of the MGA that the day runs from dawn to dusk. Dawn for this
1633    /// calculation is 90 minutes *zmaniyos* before sunrise and dusk is 90
1634    /// minutes *zmaniyos* after sunset. This day is split into 12 equal parts
1635    /// with each part being a *shaah zmanis*. This is 1/8th of the day from
1636    /// sunrise to sunset.
1637    pub fn shaah_zmanis_90_minutes_zmanis(&self) -> Option<TimeDelta> {
1638        Some(zmanim_calculator::shaah_zmanis(
1639            &self.alos_90_minutes_zmanis()?,
1640            &self.tzais_90_minutes_zmanis()?,
1641        ))
1642    }
1643
1644    // 96 minutes
1645    /// Returns *alos* (dawn) calculated using 96 minutes before
1646    /// sunrise or sea level sunrise (depending on `use_elevation`) that is
1647    /// based on the time to walk the distance of 4 *mil* at 24 minutes a *
1648    /// mil*. Time based offset calculations for *alos* are based on the
1649    /// opinion of the *Rishonim* who stated that the time of the *Neshef* (time
1650    /// between dawn and sunrise) does not vary by the time of year or location
1651    /// but purely depends on the time it takes to walk the distance of 4 *mil*.
1652    pub fn alos_96_minutes(&self) -> Option<DateTime<Tz>> {
1653        self.alos(&Minutes(96.0))
1654    }
1655
1656    /// Returns the latest *zman krias shema* (time to recite
1657    /// *Shema* in the morning) according to the opinion of the *Magen
1658    /// Avraham* (MGA) based on *alos*being 96 minutes before sunrise. This
1659    /// time is 3 *shaos zmaniyos* (solar hours) after dawn based on the
1660    /// opinion of the MGA that the day is calculated from a dawn of 96
1661    /// minutes before sunrise to nightfall of 96 minutes after sunset. This
1662    /// Returns the time of `self.alos_96_minutes() +
1663    /// (self.shaah_zmanis_96_minutes()? * 3.0)`
1664    pub fn sof_zman_shema_mga_96_minutes(&self) -> Option<DateTime<Tz>> {
1665        Some(zmanim_calculator::sof_zman_shema(
1666            &self.alos_96_minutes()?,
1667            &self.tzais_96_minutes()?,
1668        ))
1669    }
1670
1671    /// Returns the latest *zman tefila* (time to recite the morning
1672    /// prayers) according to the opinion of the *Magen Avraham* (MGA) based on
1673    /// *alos*being 96 minutes before sunrise. This time is 4 *shaos zmaniyos*
1674    /// (solar hours) after dawn based on the opinion of the MGA that the day is
1675    /// calculated from a dawn of 96 minutes before sunrise to nightfall of 96
1676    /// minutes after sunset. This returns the time of `self.alos_96_minutes()?
1677    /// + (self.shaah_zmanis_96_minutes()? * 4.0)`
1678    pub fn sof_zman_tefila_mga_96_minutes(&self) -> Option<DateTime<Tz>> {
1679        Some(zmanim_calculator::sof_zman_tefila(
1680            &self.alos_96_minutes()?,
1681            &self.tzais_96_minutes()?,
1682        ))
1683    }
1684
1685    /// Returns the time of *plag hamincha* according to the *Magen
1686    /// Avraham* with the day starting 96 minutes before sunrise and ending 96
1687    /// minutes after sunset. This is calculated as 10.75 hours after dawn. The
1688    /// formula used is `self.alos_96_minutes()? +
1689    /// (self.shaah_zmanis_96_minutes()? * 10.75)`. Since *plag* by this
1690    /// calculation can occur after sunset, it should only be used *lechumra*.
1691    pub fn plag_mga_96_minutes(&self) -> Option<DateTime<Tz>> {
1692        Some(zmanim_calculator::plag_hamincha(
1693            &self.alos_96_minutes()?,
1694            &self.tzais_96_minutes()?,
1695        ))
1696    }
1697
1698    /// A method to return *tzais hakochavim* (dusk) calculated as 96 minutes
1699    /// after sea level sunset. For information on how this is calculated
1700    /// see the documentation on
1701    /// [alos_96_minutes](ComplexZmanimCalendar::alos_96_minutes).
1702    pub fn tzais_96_minutes(&self) -> Option<DateTime<Tz>> {
1703        self.tzais(&Minutes(96.0))
1704    }
1705
1706    /// Returns a *shaah zmanis* (temporal hour) calculated using a dip
1707    /// of 96 minutes. This calculation divides the day based on the opinion of
1708    /// the *Magen Avraham* (MGA) that the day runs from dawn to dusk. Dawn for
1709    /// this calculation is 96 minutes before sunrise and dusk is 96 minutes
1710    /// after sunset. This day is split into 12 equal parts with each part being
1711    /// a *shaah zmanis*.
1712    pub fn shaah_zmanis_96_minutes(&self) -> Option<TimeDelta> {
1713        Some(zmanim_calculator::shaah_zmanis(
1714            &self.alos_96_minutes()?,
1715            &self.tzais_96_minutes()?,
1716        ))
1717    }
1718
1719    // 96 minutes zmanis
1720    /// Returns *alos* (dawn) calculated using 96 minutes *zmaniyos*
1721    /// or 1/7.5th of the day before sunrise or sea level sunrise (depending on
1722    /// `use_elevation`). This is based on a 24-minute *mil* so the time for
1723    /// 4 *mil* is 96 minutes which is 1/7.5th of a day `(12 * 60) / 7.5 =
1724    /// 96`. The day is calculated from sea level sunrise to sea level
1725    /// sunset or sunrise to sunset (depending on `use_elevation`). The actual
1726    /// calculation used is `astronomical_calculator::sunrise(&self.date,
1727    /// &self.geo_location) - (&self.shaah_zmanis_gra()? * 1.6)`.
1728    pub fn alos_96_minutes_zmanis(&self) -> Option<DateTime<Tz>> {
1729        self.alos(&MinutesZmaniyos {
1730            minutes_zmaniyos: 96.0,
1731            shaah_zmanis: &self.shaah_zmanis_gra()?,
1732        })
1733    }
1734
1735    /// Returns the latest *zman krias shema* (time to recite
1736    /// *Shema* in the morning) according to the opinion of the *Magen
1737    /// Avraham* (MGA) based on *alos* being 96 minutes *zmaniyos* before
1738    /// sunrise. This time is 3 *shaos zmaniyos* (solar hours) after dawn
1739    /// based on the opinion of the MGA that the day is calculated from a
1740    /// dawn of 96 minutes *zmaniyos* before sea level sunrise to nightfall of
1741    /// 96 minutes *zmaniyos* after sea level sunset. This returns the time
1742    /// of `self.alos_96_minutes_zmanis()? +
1743    /// (self.shaah_zmanis_96_minutes_zmanis()? * 3.0)`
1744    pub fn sof_zman_shema_mga_96_minutes_zmanis(&self) -> Option<DateTime<Tz>> {
1745        Some(zmanim_calculator::sof_zman_shema(
1746            &self.alos_96_minutes_zmanis()?,
1747            &self.tzais_96_minutes_zmanis()?,
1748        ))
1749    }
1750
1751    /// Returns the latest *zman tefila* (time to recite the morning
1752    /// prayers) according to the opinion of the *Magen Avraham* (MGA) based on
1753    /// *alos*being 96 minutes *zmaniyos* before sunrise. This time is 4 *shaos
1754    /// zmaniyos* (solar hours) after dawn based on the opinion of the MGA
1755    /// that the day is calculated from a dawn of 96 minutes *zmaniyos*
1756    /// before sunrise to nightfall of 96 minutes *zmaniyos* after sunset.
1757    /// This returns the time of `self.alos_96_minutes_zmanis()? +
1758    /// (self.shaah_zmanis_96_minutes_zmanis()? * 4.0)`
1759    pub fn sof_zman_tefila_mga_96_minutes_zmanis(&self) -> Option<DateTime<Tz>> {
1760        Some(zmanim_calculator::sof_zman_tefila(
1761            &self.alos_96_minutes_zmanis()?,
1762            &self.tzais_96_minutes_zmanis()?,
1763        ))
1764    }
1765
1766    /// Returns the time of *plag hamincha* according to the *Magen
1767    /// Avraham* with the day starting 96 minutes *zmaniyos* before sunrise and
1768    /// ending 96 minutes *zmaniyos* after sunset. This is calculated as
1769    /// 10.75 hours after dawn. The formula used is
1770    /// `self.alos_96_minutes_zmanis()? +
1771    /// (self.shaah_zmanis_96_minutes_zmanis()? * 10.75)`. Since *plag* by this
1772    /// calculation can occur after sunset, it should only be used *lechumra*.
1773    pub fn plag_mga_96_minutes_zmanis(&self) -> Option<DateTime<Tz>> {
1774        Some(zmanim_calculator::plag_hamincha(
1775            &self.alos_96_minutes_zmanis()?,
1776            &self.tzais_96_minutes_zmanis()?,
1777        ))
1778    }
1779
1780    /// Returns *tzais hakochavim* (dusk) calculated using 96 minutes
1781    /// *zmaniyos* or 1/7.5 of the day after sea level sunset.
1782    pub fn tzais_96_minutes_zmanis(&self) -> Option<DateTime<Tz>> {
1783        self.tzais(&MinutesZmaniyos {
1784            minutes_zmaniyos: 96.0,
1785            shaah_zmanis: &self.shaah_zmanis_gra()?,
1786        })
1787    }
1788
1789    /// Returns a *shaah zmanis** (temporal hour) according to the
1790    /// opinion of the *Magen Avraham* (MGA) based on *alos* being 96 minutes
1791    /// *zmaniyos* before sunrise. This calculation divides the day based on the
1792    /// opinion of the MGA that the day runs from dawn to dusk. Dawn for this
1793    /// calculation is 96 minutes *zmaniyos* before sunrise and dusk is 96
1794    /// minutes *zmaniyos* after sunset. This day is split into 12 equal parts
1795    /// with each part being a *shaah zmanis*. This is 1/7.5th of the day from
1796    /// sunrise to sunset.
1797    pub fn shaah_zmanis_96_minutes_zmanis(&self) -> Option<TimeDelta> {
1798        Some(zmanim_calculator::shaah_zmanis(
1799            &self.alos_96_minutes_zmanis()?,
1800            &self.tzais_96_minutes_zmanis()?,
1801        ))
1802    }
1803
1804    // 120 minutes
1805    /// This method should be used *lechumra* only and returns *alos* (dawn)
1806    /// calculated using 120 minutes before sea level sunrise (no adjustment for
1807    /// elevation is made) based on the time to walk the distance of 5 *mil*
1808    /// (Ula) at 24 minutes a *mil*. Time based offset calculations for
1809    /// *alos* are based on the* opinion of the Rishonim who stated that the
1810    /// time of the *neshef* (time between dawn and sunrise) does not vary
1811    /// by the time of year or location but purely depends on the time it
1812    /// takes to walk the distance of 5 *mil* (Ula). Since this time is
1813    /// extremely early, it should only be used *lechumra*, such as not
1814    /// eating after this time on a fast day, and **not** as the start time
1815    /// for *mitzvos* that can only be performed during the day.
1816    pub fn alos_120_minutes(&self) -> Option<DateTime<Tz>> {
1817        self.alos(&Minutes(120.0))
1818    }
1819
1820    /// Returns the latest *zman krias shema* (time to recite
1821    /// *Shema* in the morning) according to the opinion of the *Magen
1822    /// Avraham* (MGA) based on *alos*being 120 minutes before sunrise. This
1823    /// time is 3 *shaos zmaniyos* (solar hours) after dawn based on the
1824    /// opinion of the MGA that the day is calculated from a dawn of 120
1825    /// minutes before sunrise to nightfall of 120 minutes after sunset. This
1826    /// Returns the time of `self.alos_120_minutes() +
1827    /// (self.shaah_zmanis_120_minutes()? * 3.0)`.  This is an extremely early
1828    /// *zman* that is very much a *chumra*.
1829    pub fn sof_zman_shema_mga_120_minutes(&self) -> Option<DateTime<Tz>> {
1830        Some(zmanim_calculator::sof_zman_shema(
1831            &self.alos_120_minutes()?,
1832            &self.tzais_120_minutes()?,
1833        ))
1834    }
1835
1836    /// Returns the latest *zman tefila* (time to recite the morning
1837    /// prayers) according to the opinion of the *Magen Avraham* (MGA) based on
1838    /// *alos*being 120 minutes before sunrise. This time is 4 *shaos zmaniyos*
1839    /// (solar hours) after dawn based on the opinion of the MGA that the day is
1840    /// calculated from a dawn of 120 minutes before sunrise to nightfall of 120
1841    /// minutes after sunset. This returns the time of
1842    /// `self.alos_120_minutes()? +
1843    /// (self.shaah_zmanis_120_minutes()? * 4.0)`
1844    pub fn sof_zman_tefila_mga_120_minutes(&self) -> Option<DateTime<Tz>> {
1845        Some(zmanim_calculator::sof_zman_tefila(
1846            &self.alos_120_minutes()?,
1847            &self.tzais_120_minutes()?,
1848        ))
1849    }
1850
1851    /// This method should be used *lechumra* only and returns the time of *plag
1852    /// hamincha* based on sunrise being 120 minutes
1853    /// before sunrise. This is calculated as 10.75 hours after dawn. The
1854    /// formula used is `self.alos_120_minutes()? + (10.75 *
1855    /// self.shaah_zmanis_120_minutes()?)`. Since the *zman* based on an
1856    /// extremely early *alos* and a very late *tzais*, it should only be
1857    /// used *lechumra*.
1858    pub fn plag_120_minutes(&self) -> Option<DateTime<Tz>> {
1859        Some(zmanim_calculator::plag_hamincha(
1860            &self.alos_120_minutes()?,
1861            &self.tzais_120_minutes()?,
1862        ))
1863    }
1864
1865    /// A method to return *tzais hakochavim* (dusk) calculated as 120 minutes
1866    /// after sea level sunset. For information on how this is calculated
1867    /// see the documentation on
1868    /// [alos_120_minutes](ComplexZmanimCalendar::alos_120_minutes).
1869    pub fn tzais_120_minutes(&self) -> Option<DateTime<Tz>> {
1870        self.tzais(&Minutes(120.0))
1871    }
1872
1873    /// Returns a *shaah zmanis* (temporal hour) calculated using a dip
1874    /// of 120 minutes. This calculation divides the day based on the opinion of
1875    /// the *Magen Avraham* (MGA) that the day runs from dawn to dusk. Dawn for
1876    /// this calculation is 120 minutes before sunrise and dusk is 120 minutes
1877    /// after sunset. This day is split into 12 equal parts with each part being
1878    /// a *shaah zmanis*. Since *zmanim* that use this method are extremely late
1879    /// or early and at a point when the sky is a long time past the 18&deg;
1880    /// point where the darkest point is reached, *zmanim* that use this
1881    /// should only be used *lechumra* only, such as delaying the start of
1882    /// nighttime *mitzvos*.
1883    pub fn shaah_zmanis_120_minutes(&self) -> Option<TimeDelta> {
1884        Some(zmanim_calculator::shaah_zmanis(
1885            &self.alos_120_minutes()?,
1886            &self.tzais_120_minutes()?,
1887        ))
1888    }
1889
1890    // 120 minutes zmanis
1891    /// This method should be used *lechumra* only and method returns *alos*
1892    /// (dawn) calculated using 120 minutes *zmaniyos* or 1/6th of the day
1893    /// before sunrise or sea level sunrise (depending on `use_elevation`).
1894    /// This is based on a 24-minute *mil* so the time for 5 mil is 120
1895    /// minutes which is 1/6th of a day `(12 * 60) / 6 = 120`. The day is
1896    /// calculated from sea level sunrise to sea level sunset or sunrise to
1897    /// sunset (depending on `use_elevation`). The actual
1898    /// calculation used is `astronomical_calculator::sunrise(&self.date,
1899    /// &self.geo_location) - (&self.shaah_zmanis_gra()? * 2.0)`. Since this
1900    /// time is extremely early, it should only be used *lechumra*, such as
1901    /// not eating after this time on a fast day, and **not** as the start
1902    /// time for *mitzvos* that can only be performed during the day.
1903    pub fn alos_120_minutes_zmanis(&self) -> Option<DateTime<Tz>> {
1904        self.alos(&MinutesZmaniyos {
1905            minutes_zmaniyos: 120.0,
1906            shaah_zmanis: &self.shaah_zmanis_gra()?,
1907        })
1908    }
1909
1910    /// This method should be used *lechumra* only and returns the time of *plag
1911    /// hamincha* based on sunrise being 120 minutes *zmaniyos* or 1/6th of the
1912    /// day before sunrise. This is calculated as 10.75 hours after dawn.
1913    /// The formula used is `self.alos_120_minutes_zmanis()? + (10.75 *
1914    /// self.shaah_zmanis_120_minutes_zmanis()?)`. Since the *zman* is based on
1915    /// an extremely early *alos* and a very late *tzais*, it should only be
1916    /// used *lechumra*.
1917    pub fn plag_120_minutes_zmanis(&self) -> Option<DateTime<Tz>> {
1918        Some(zmanim_calculator::plag_hamincha(
1919            &self.alos_120_minutes_zmanis()?,
1920            &self.tzais_120_minutes_zmanis()?,
1921        ))
1922    }
1923
1924    /// This method should be used *lechumra* only and returns *tzais* (dusk)
1925    /// calculated using 120 minutes *zmaniyos* after sunset. Since the
1926    /// *zman* is extremely late and at a time when the sun is well below the
1927    /// 18&deg; point (scientifically the darkest point) in most places on the
1928    /// globe, it should only be used *lechumra*, such as delaying the start
1929    /// of nighttime mitzvos.
1930    pub fn tzais_120_minutes_zmanis(&self) -> Option<DateTime<Tz>> {
1931        self.tzais(&MinutesZmaniyos {
1932            minutes_zmaniyos: 120.0,
1933            shaah_zmanis: &self.shaah_zmanis_gra()?,
1934        })
1935    }
1936
1937    /// Returns a *shaah zmanis* (temporal hour) calculated using a dip
1938    /// of 120 minutes. This calculation divides the day based on the opinion of
1939    /// the *Magen Avraham* (MGA) that the day runs from dawn to dusk. Dawn for
1940    /// this calculation is 120 minutes before sunrise and dusk is 120 minutes
1941    /// after sunset. This day is split into 12 equal parts with each part being
1942    /// a *shaah zmanis*. This is identical to 1/6th of the day from sunrise to
1943    /// sunset. Since *zmanim* that use this method are extremely late
1944    /// or early and at a point when the sky is a long time past the 18&deg;
1945    /// point where the darkest point is reached, *zmanim* that use this
1946    /// should only be used *lechumra* only, such as delaying the start of
1947    /// nighttime *mitzvos*.
1948    pub fn shaah_zmanis_120_minutes_zmanis(&self) -> Option<TimeDelta> {
1949        Some(zmanim_calculator::shaah_zmanis(
1950            &self.alos_120_minutes_zmanis()?,
1951            &self.tzais_120_minutes_zmanis()?,
1952        ))
1953    }
1954
1955    // Other Misheyakir
1956    /// Returns *misheyakir* based on the position of the sun when
1957    /// it is 11.5&deg; below geometric zenith (90&deg;). This calculation is
1958    /// used for calculating *misheyakir* according to some opinions. This
1959    /// calculation is based on the position of the sun 52 minutes before
1960    /// sunrise in Jerusalem around the equinox / equilux, which calculates
1961    /// to 11.5&deg; below geometric zenith.
1962    pub fn misheyakir_11_5_degrees(&self) -> Option<DateTime<Tz>> {
1963        self.alos(&Degrees(11.5))
1964    }
1965
1966    /// Returns *misheyakir* based on the position of the sun when
1967    /// it is 11&deg; below geometric zenith (90&deg;). This calculation is used
1968    /// for calculating *misheyakir* according to some opinions. This
1969    /// calculation is based on the position of the sun 48 minutes before
1970    /// sunrise in Jerusalem around the equinox / equilux, which calculates
1971    /// to 11&deg; below geometric zenith.
1972    pub fn misheyakir_11_degrees(&self) -> Option<DateTime<Tz>> {
1973        self.alos(&Degrees(11.0))
1974    }
1975
1976    /// Returns *misheyakir* based on the position of the sun when
1977    /// it is 10.2&deg; below geometric zenith (90&deg;). This calculation is
1978    /// used for calculating *misheyakir* according to some opinions. This
1979    /// calculation is based on the position of the sun 45 minutes before
1980    /// sunrise in Jerusalem around the equinox which calculates to 10.2&deg;
1981    /// below geometric zenith.
1982    pub fn misheyakir_10_2_degrees(&self) -> Option<DateTime<Tz>> {
1983        self.alos(&Degrees(10.2))
1984    }
1985
1986    /// Returns *misheyakir* based on the position of the sun when
1987    /// it is 9.5&deg; below geometric zenith (90&deg;). This calculation is
1988    /// based on Rabbi Dovid Kronglass's Calculation of 45 minutes in
1989    /// Baltimore as mentioned in *Divrei Chachamim* No. 24 brought down by
1990    /// the *Birur Halacha*, *Tinyana*, Ch. 18. This calculates to 9.5&deg;.
1991    /// Also see Rabbi Yaakov Yitzchok Neiman in *Kovetz Eitz Chaim* Vol. 9,
1992    /// p. 202 that the *Vya'an Yosef* did not want to rely on times earlier
1993    /// than 45 minutes in New York. This *zman* is also used in the
1994    /// calendars published by Rabbi Hershel Edelstein. As mentioned in
1995    /// Yisroel Vehazmanim, Rabbi Edelstein who was given the 45 minute
1996    /// *zman* by Rabbi Bick. The calendars published by the *Edot
1997    /// Hamizrach* communities also use this *zman*. This also follows the
1998    /// opinion of Rabbi Shmuel Kamenetsky who provided the time of 36 and
1999    /// 45 minutes, but did not provide a degree-based time. Since this
2000    /// *zman* depends on the level of light, Rabbi Yaakov Shakow presented
2001    /// these degree-based times to Rabbi Shmuel Kamenetsky who agreed to
2002    /// them.
2003    pub fn misheyakir_9_5_degrees(&self) -> Option<DateTime<Tz>> {
2004        self.alos(&Degrees(9.5))
2005    }
2006
2007    /// Returns *misheyakir* based on the position of the sun when
2008    /// it is 7.65&deg; below geometric zenith (90&deg;). The degrees are based
2009    /// on a 35/36 minute *zman* around the equinox / equilux, when the
2010    /// *neshef* (twilight) is the shortest. This time is based on Rabbi
2011    /// Moshe Feinstein who writes in *Ohr Hachaim* Vol. 4, Ch. 6 that
2012    /// *misheyakir* in New York is 35-40 minutes before sunrise, something
2013    /// that is a drop less than 8&deg;. Rabbi Yisroel Taplin in *Zmanei
2014    /// Yisrael* (page 117) notes that Rabbi Yaakov Kamenetsky stated that
2015    /// it is not less than 36 minutes before sunrise (maybe it is
2016    /// 40 minutes). *Sefer Yisrael Vehazmanim* (p. 7) quotes the *Tamar
2017    /// Yifrach* in the name of the Satmar Rov that one should be stringent
2018    /// not consider *misheyakir* before 36 minutes. This is also the
2019    /// accepted *minhag* in Lakewood that is used in the Yeshiva. This
2020    /// follows the opinion of Rabbi Shmuel Kamenetsky who provided the time
2021    /// of 35/36 minutes, but did not provide a degree-based time. Since
2022    /// this *zman* depends on the level of light, Rabbi Yaakov Shakow
2023    /// presented this degree-based calculations to Rabbi Shmuel Kamenetsky
2024    /// who agreed to them.
2025    pub fn misheyakir_7_65_degrees(&self) -> Option<DateTime<Tz>> {
2026        self.alos(&Degrees(7.65))
2027    }
2028
2029    // Bein Hashmashos Yereim
2030    /// Returns the beginning of *bein hashmashos* (twilight)
2031    /// according to the Yereim (Rabbi Eliezer of Metz) calculated as 18 minutes
2032    /// or 3/4 of a 24-minute mil before sunset. According to the Yereim, bein
2033    /// hashmashos starts 3/4 of a mil before sunset and *tzais* or nightfall
2034    /// starts at sunset.
2035    pub fn bein_hashmashos_yereim_18_minutes(&self) -> Option<DateTime<Tz>> {
2036        self.tzais(&Minutes(-18.0))
2037    }
2038
2039    /// Returns the beginning of *bein hashmashos* (twilight)
2040    /// according to the Yereim (Rabbi Eliezer of Metz) calculated as the sun's
2041    /// position 3.05&deg; above the horizon around the equinox / equilux, its
2042    /// position 18 minutes or 3/4 of an 24-minute mil before sunset. According
2043    /// to the Yereim, *bein hashmashos* starts 3/4 of a mil before sunset and
2044    /// *tzais* or nightfall starts at sunset. Note that lechumra (of about 14
2045    /// seconds) a refraction value of 0.5166&deg; as opposed to the traditional
2046    /// 0.566&deg; is used. This is more inline with the actual refraction in
2047    /// Eretz Yisrael and is brought down by Rabbi Yedidya Manet in his
2048    /// Zmanei Halacha Lema'aseh (p. 11). That is the first source that I am
2049    /// aware of that calculates degree-based Yereim zmanim. The 0.5166&deg;
2050    /// refraction is also used by the Luach Itim Lebinah. Calculating the
2051    /// Yereim's *bein hashmashos* using 18-minute based degrees is also
2052    /// suggested in the upcoming 8th edition of the zmanim Kehilchasam. For
2053    /// more details, see the article The Yereim's Bein Hashmashos.
2054    pub fn bein_hashmashos_yereim_3_05_degrees(&self) -> Option<DateTime<Tz>> {
2055        self.tzais(&Degrees(-3.05))
2056    }
2057
2058    /// Returns the beginning of *bein hashmashos* (twilight)
2059    /// according to the Yereim (Rabbi Eliezer of Metz) calculated as 16.875
2060    /// minutes or 3/4 of a 22.5-minute mil before sunset. According to the
2061    /// Yereim, *bein hashmashos* starts 3/4 of a mil before sunset and *tzais*
2062    /// or nightfall starts at sunset.
2063    pub fn bein_hashmashos_yereim_16_875_minutes(&self) -> Option<DateTime<Tz>> {
2064        self.tzais(&Minutes(-16.875))
2065    }
2066
2067    /// Returns the beginning of *bein hashmashos* (twilight)
2068    /// according to the Yereim (Rabbi Eliezer of Metz) calculated as the sun's
2069    /// position 2.8&deg; above the horizon around the equinox / equilux, its
2070    /// position 16.875 minutes or 3/4 of an 18-minute mil before sunset.
2071    /// According to the Yereim, *bein hashmashos* starts 3/4 of a mil before
2072    /// sunset and *tzais* or nightfall starts at sunset. Details, including how
2073    /// the degrees were calculated can be seen in the documentation of
2074    /// [bein_hashmashos_yereim_3_05_degrees](ComplexZmanimCalendar::bein_hashmashos_yereim_3_05_degrees).
2075    pub fn bein_hashmashos_yereim_2_8_degrees(&self) -> Option<DateTime<Tz>> {
2076        self.tzais(&Degrees(-2.8))
2077    }
2078
2079    /// Returns the beginning of *bein hashmashos* (twilight)
2080    /// according to the Yereim (Rabbi Eliezer of Metz) calculated as 13.5
2081    /// minutes or 3/4 of an 18-minute mil before sunset. According to the
2082    /// Yereim, *bein hashmashos* starts 3/4 of a mil before sunset and *tzais*
2083    /// or nightfall starts at sunset.
2084    pub fn bein_hashmashos_yereim_13_5_minutes(&self) -> Option<DateTime<Tz>> {
2085        self.tzais(&Minutes(-13.5))
2086    }
2087
2088    /// Returns the beginning of *bein hashmashos* according to the
2089    /// Yereim (Rabbi Eliezer of Metz) calculated as the sun's position 2.1&deg;
2090    /// above the horizon around the equinox / equilux in Yerushalayim, its
2091    /// position 13.5 minutes or 3/4 of an 18-minute mil before sunset.
2092    /// According to the Yereim, *bein hashmashos* starts 3/4 of a mil before
2093    /// sunset and *tzais* or nightfall starts at sunset. Details, including how
2094    /// the degrees were calculated can be seen in the documentation of
2095    /// [bein_hashmashos_yereim_3_05_degrees](ComplexZmanimCalendar::bein_hashmashos_yereim_3_05_degrees).
2096    pub fn bein_hashmashos_yereim_2_1_degrees(&self) -> Option<DateTime<Tz>> {
2097        self.tzais(&Degrees(-2.1))
2098    }
2099
2100    // Bein Hashmashos Rabeinu Tam
2101    /// Method to return the beginning of *bein hashmashos* of Rabbeinu Tam
2102    /// calculated when the sun is 13.24&deg; below the western geometric
2103    /// horizon (90&deg;) after sunset. This calculation is based on the
2104    /// same calculation of [*bein hashmashos* Rabbeinu Tam
2105    /// 58.5](ComplexZmanimCalendar::bein_hashmashos_rt_58_5_minutes) minutes
2106    /// but uses a degree-based calculation instead of 58.5 exact minutes.
2107    /// This calculation is based on the position of the sun 58.5 minutes
2108    /// after sunset in Jerusalem around the equinox / equilux, which
2109    /// calculates to 13.24&deg; below geometric zenith. NOTE: As per
2110    /// Yisrael Vehazmanim Vol. III page 1028, No. 50, a dip of slightly
2111    /// less than 13&deg; should be used. Calculations show that the proper
2112    /// dip to be 13.2456&deg; (truncated to 13.24 that provides about 1.5
2113    /// second earlier (*lechumra*) time) below the horizon at that time. This
2114    /// makes a difference of 1 minute and 10 seconds in Jerusalem during the
2115    /// Equinox, and 1 minute 29 seconds during the solstice as compared to the
2116    /// proper 13.24&deg; versus 13&deg;. For NY during the solstice, the
2117    /// difference is 1 minute 56 seconds.
2118    pub fn bein_hashmashos_rt_13_24_degrees(&self) -> Option<DateTime<Tz>> {
2119        self.tzais(&Degrees(13.24))
2120    }
2121
2122    /// This method returns the beginning of *bein hashmashos* of Rabbeinu Tam
2123    /// calculated as a 58.5-minute offset after sunset. *bein hashmashos* is
2124    /// 3/4 of a mil before *tzais* or 3 1/4 mil after sunset. With a mil
2125    /// calculated as 18 minutes, 3.25 * 18 = 58.5 minutes.
2126    pub fn bein_hashmashos_rt_58_5_minutes(&self) -> Option<DateTime<Tz>> {
2127        self.tzais(&Minutes(58.5))
2128    }
2129
2130    /// This method returns the beginning of *bein hashmashos* based on the
2131    /// calculation of 13.5 minutes (3/4 of an 18-minute mil) before *shkiah*
2132    /// calculated as 7.083&deg;.
2133    pub fn bein_hashmashos_rt_13_5_minutes_before_7_083_degrees(&self) -> Option<DateTime<Tz>> {
2134        Some(self.tzais_geonim_7_083_degrees()? - TimeDelta::seconds(810))
2135    }
2136
2137    /// This method returns the beginning of *bein hashmashos* of Rabbeinu Tam
2138    /// calculated according to the opinion of the Divrei Yosef (see Yisrael
2139    /// Vehazmanim) calculated 5/18th (27.77%) of the time between alos
2140    /// (calculated as 19.8&deg; before sunrise) and sunrise. This is added to
2141    /// sunset to arrive at the time for *bein hashmashos* of Rabbeinu Tam.
2142    pub fn bein_hashmashos_rt_2_stars(&self) -> Option<DateTime<Tz>> {
2143        let offset_seconds =
2144            (self.hanetz()? - self.alos_19_8_degrees()?).as_seconds_f64() * (5.0 / 18.0);
2145        let offset_delta = TimeDelta::seconds(offset_seconds.trunc() as i64)
2146            + TimeDelta::nanoseconds((offset_seconds.fract() * 1_000_000_000.0) as i64);
2147        Some(self.shkia()? + offset_delta)
2148    }
2149
2150    // Other Tzais
2151    /// Returns the *tzais hakochavim* (nightfall) based on the
2152    /// opinion of the *Geonim* calculated at the sun's position at 3.7&deg;
2153    /// below the western horizon. This is a very early *zman* and should not be
2154    /// relied on without Rabbinical guidance.
2155    pub fn tzais_geonim_3_7_degrees(&self) -> Option<DateTime<Tz>> {
2156        self.tzais(&Degrees(3.7))
2157    }
2158
2159    /// Returns the *tzais hakochavim* (nightfall) based on the
2160    /// opinion of the *Geonim* calculated at the sun's position at 3.8&deg;
2161    /// below the western horizon. This is a very early *zman* and should not be
2162    /// relied on without Rabbinical guidance.
2163    pub fn tzais_geonim_3_8_degrees(&self) -> Option<DateTime<Tz>> {
2164        self.tzais(&Degrees(3.8))
2165    }
2166
2167    /// Returns the *tzais hakochavim* (nightfall) based on the
2168    /// opinion of the *Geonim* calculated as 3/4 of a *mil*, based on a
2169    /// 22.5-minute *mil*, or 16 7/8 minutes. It is the sun's position at
2170    /// 4.37&deg; below the western horizon. This is a very early *zman* and
2171    /// should not be relied on without Rabbinical guidance.
2172    pub fn tzais_geonim_4_37_degrees(&self) -> Option<DateTime<Tz>> {
2173        self.tzais(&Degrees(4.37))
2174    }
2175
2176    /// Returns the *tzais hakochavim* (nightfall) based on the
2177    /// opinion of the *Geonim* calculated as 3/4 of a *mil* based on a
2178    /// 24-minute *mil*, or 18 minutes. It is the sun's position at 4.61&deg;
2179    /// below the western horizon. This is a very early *zman* and should
2180    /// not be relied on without Rabbinical guidance.
2181    pub fn tzais_geonim_4_61_degrees(&self) -> Option<DateTime<Tz>> {
2182        self.tzais(&Degrees(4.61))
2183    }
2184
2185    /// Returns the *tzais* (nightfall) based on the opinion of the
2186    /// *Geonim* calculated as 3/4 of a *mil* based on the sun's position at
2187    /// 4.8&deg; below the western horizon. This is based on Rabbi Leo Levi's
2188    /// calculations. This is a very early *zman* and should not be relied on
2189    /// without Rabbinical guidance.
2190    pub fn tzais_geonim_4_8_degrees(&self) -> Option<DateTime<Tz>> {
2191        self.tzais(&Degrees(4.8))
2192    }
2193
2194    /// Returns the *tzais* (nightfall) based on the opinion of the
2195    /// *Geonim* calculated as 3/4 of a 24-minute *mil*, based on a mil being 24
2196    /// minutes, and is calculated as 18 + 2 + 4 for a total of 24 minutes. It
2197    /// is the sun's position at 5.88&deg; below the western horizon. This is a
2198    /// very early *zman* and should not be relied on without Rabbinical
2199    /// guidance.
2200    pub fn tzais_geonim_5_88_degrees(&self) -> Option<DateTime<Tz>> {
2201        self.tzais(&Degrees(5.88))
2202    }
2203
2204    /// Returns the *tzais hakochavim* (nightfall) based on the
2205    /// opinion of the *Geonim* calculated at the sun's position at 5.95&deg;
2206    /// below the western horizon. This is a very early *zman* and should not be
2207    /// relied on without Rabbinical guidance.
2208    pub fn tzais_geonim_5_95_degrees(&self) -> Option<DateTime<Tz>> {
2209        self.tzais(&Degrees(5.95))
2210    }
2211
2212    /// Returns the *tzais* (nightfall) based on the opinion of the
2213    /// *Geonim* as calculated by Rabbi Yechiel Michel Tucazinsky. It is based
2214    /// on of the position of the sun no later than 31 minutes after sunset
2215    /// in Jerusalem the height of the summer solstice and is 28 minutes
2216    /// after *shkiah* around the equinox / equilux. This computes to 6.45&deg;
2217    /// below the western horizon.
2218    pub fn tzais_geonim_6_45_degrees(&self) -> Option<DateTime<Tz>> {
2219        self.tzais(&Degrees(6.45))
2220    }
2221
2222    /// Returns the *tzais hakochavim* (nightfall) based on the
2223    /// opinion of the *Geonim* calculated when the sun's position 7.083&deg;
2224    /// (or 7&deg; 5′) below the western horizon. This is often referred to
2225    /// as 7&deg;5' or 7&deg; and 5 minutes. This calculation is based on
2226    /// the observation of 3 medium-sized stars by Dr. Baruch (Berthold)
2227    /// Cohn in his luach Tabellen enthaltend die Zeitangaben für den Beginn
2228    /// der Nacht und des Tages für die Breitengrade + 66 bis -38 published
2229    /// in Strasbourg, France in 1899. This calendar was very popular in
2230    /// Europe, and many other calendars based their time on it. Rav Dovid
2231    /// Tzvi Hoffman in his *Sh"Ut Melamed Leho'il* in an exchange of
2232    /// letters with Baruch Cohn in *Orach Chaim* 30 agreed to this *zman*
2233    /// (page 36), as did the *Sh"Ut Bnei Tziyon* and the *Tenuvas
2234    /// Sadeh*. It is very close to the time of the *Mekor Chesed* of the *Sefer
2235    /// chasidim*. It is close to the position of the sun 30 minutes after
2236    /// sunset in Jerusalem around the equinox / equilux, but not Exactly. The
2237    /// actual position of the sun 30 minutes after sunset in Jerusalem at the
2238    /// equilux is 7.205&deg; and 7.199&deg; at the equinox. See *Hazmanim
2239    /// Bahalacha* vol 2, pages 520-521 for more details.
2240    pub fn tzais_geonim_7_083_degrees(&self) -> Option<DateTime<Tz>> {
2241        self.tzais(&Degrees(7.083))
2242    }
2243
2244    /// Returns *tzais* (nightfall) based on the opinion of the
2245    /// Geonim calculated as 45 minutes after sunset during the summer solstice
2246    /// in New York, when the *neshef* (twilight) is the longest. The sun's
2247    /// position at this time computes to 7.75&deg; below the western horizon.
2248    /// See Igros Moshe Even Haezer 4, Ch. 4 (regarding *tzais* for *krias
2249    /// Shema*). It is also mentioned in Rabbi Heber's *Shaarei Zmanim* on in
2250    /// chapter 10 (page 87) and chapter 12 (page 108). Also see the time of 45
2251    /// minutes in Rabbi Simcha Bunim Cohen's The radiance of Shabbos as the
2252    /// earliest *zman* for New York. This *zman* is also listed in the *Divrei
2253    /// Shalom* Vol. III, chapter 75, and *Bais Av"i* Vol. III, chapter 117.
2254    /// This *zman* is also listed in the *Divrei Shalom* etc. chapter 177
2255    /// (FIXME - could not be located). Since this *zman* depends on the level
2256    /// of light, Rabbi Yaakov Shakow presented this degree-based calculation to
2257    /// Rabbi Rabbi Shmuel Kamenetsky who agreed to it.
2258    pub fn tzais_geonim_7_67_degrees(&self) -> Option<DateTime<Tz>> {
2259        self.tzais(&Degrees(7.67))
2260    }
2261
2262    /// Returns *tzais* (nightfall) when the sun is 8.5&deg; below the geometric
2263    /// horizon (90&deg;) after sunset, a time that Rabbi Meir Posen in his the
2264    /// *Ohr Meir* calculated that 3 small stars are visible, which is later
2265    /// than the required 3 medium stars. This calculation is based on the sun's
2266    /// position below the horizon 36 minutes after sunset in Jerusalem around
2267    /// the equinox / equilux.
2268    pub fn tzais_geonim_8_5_degrees(&self) -> Option<DateTime<Tz>> {
2269        self.tzais(&Degrees(8.5))
2270    }
2271
2272    /// Returns the *tzais* (nightfall) based on the calculations
2273    /// used in the *Luach Itim Lebinah* as the stringent time for *tzais*. It
2274    /// is calculated at the sun's position at 9.3&deg; below the western
2275    /// horizon.
2276    pub fn tzais_geonim_9_3_degrees(&self) -> Option<DateTime<Tz>> {
2277        self.tzais(&Degrees(9.3))
2278    }
2279
2280    /// Returns the *tzais* (nightfall) based on the opinion of the
2281    /// *Geonim* calculated as 60 minutes after sunset around the equinox /
2282    /// equilux, the day that a solar hour is 60 minutes in New York. The sun's
2283    /// position at this time computes to 9.75&deg; below the western horizon.
2284    /// This is the opinion of Rabbi Eliyahu Henkin. This also follows the
2285    /// opinion of Rabbi Shmuel Kamenetsky. Rabbi Yaakov Shakow presented
2286    /// these degree-based times to Rabbi Shmuel Kamenetsky who agreed to
2287    /// them.
2288    pub fn tzais_geonim_9_75_degrees(&self) -> Option<DateTime<Tz>> {
2289        self.tzais(&Degrees(9.75))
2290    }
2291}
2292
2293/// When to use elevation for *zmanim* calculations. See the documentation of
2294/// [zmanim_calculator] for some discussion of this
2295pub enum UseElevation {
2296    /// Never use elevation
2297    No,
2298    /// Only use elevation directly for *hanetz* and *shkia*
2299    HanetzShkia,
2300    /// Always use elevation
2301    All,
2302}
2303
2304impl UseElevation {
2305    /// Convert the `UseElevation` into a `bool` for
2306    /// [zmanim_calculator] functions. The param
2307    /// `hanetz_or_shkia` should be `true` if the calling function is
2308    /// calculating *hanetz* or *shkia*, and `false` otherwise
2309    pub fn to_bool(&self, hanetz_or_shkia: bool) -> bool {
2310        match &self {
2311            Self::No => false,
2312            Self::HanetzShkia => hanetz_or_shkia,
2313            Self::All => true,
2314        }
2315    }
2316}
2317
2318#[cfg(test)]
2319mod tests {
2320    use super::*;
2321    use chrono::TimeZone;
2322    use chrono_tz::Asia::Jerusalem;
2323
2324    #[test]
2325    fn test_fixed_local_chatzos() {
2326        let loc1 = GeoLocation {
2327            latitude: 31.79388,
2328            longitude: 35.03684,
2329            elevation: 586.19,
2330            timezone: Jerusalem,
2331        };
2332        let date1 = Jerusalem.with_ymd_and_hms(2025, 8, 4, 0, 0, 0).unwrap();
2333        let czc1 = ComplexZmanimCalendar {
2334            geo_location: loc1,
2335            date: date1,
2336            use_elevation: UseElevation::No,
2337        };
2338        let chatzos1 = czc1.fixed_local_chatzos().unwrap().to_string();
2339        assert_eq!(chatzos1, "2025-08-04 12:39:51.158400 IDT"); // off by < 1 ms
2340
2341        let loc2 = GeoLocation {
2342            latitude: 31.0,
2343            longitude: 35.0,
2344            elevation: 586.19,
2345            timezone: Jerusalem,
2346        };
2347        let date2 = Jerusalem.with_ymd_and_hms(2025, 1, 4, 0, 0, 0).unwrap();
2348        let czc2 = ComplexZmanimCalendar {
2349            geo_location: loc2,
2350            date: date2,
2351            use_elevation: UseElevation::No,
2352        };
2353        let chatzos2 = czc2.fixed_local_chatzos().unwrap().to_string();
2354        assert_eq!(chatzos2, "2025-01-04 11:40:00 IST");
2355    }
2356
2357    #[test]
2358    fn test_alos_120_minutes() {
2359        let loc = GeoLocation {
2360            latitude: 31.79388,
2361            longitude: 35.03684,
2362            elevation: 586.19,
2363            timezone: Jerusalem,
2364        };
2365
2366        let date1 = Jerusalem.with_ymd_and_hms(2025, 8, 4, 0, 0, 0).unwrap();
2367        let czc1 = ComplexZmanimCalendar {
2368            geo_location: loc.clone(),
2369            date: date1,
2370            use_elevation: UseElevation::No,
2371        };
2372        let alos1 = czc1.alos_120_minutes().unwrap().to_string();
2373        assert_eq!(alos1, "2025-08-04 03:57:34.359480109 IDT");
2374
2375        let date2 = Jerusalem.with_ymd_and_hms(2025, 1, 26, 0, 0, 0).unwrap();
2376        let czc2 = ComplexZmanimCalendar {
2377            geo_location: loc.clone(),
2378            date: date2,
2379            use_elevation: UseElevation::No,
2380        };
2381        let alos2 = czc2.alos_120_minutes().unwrap().to_string();
2382        assert_eq!(alos2, "2025-01-26 04:36:28.393758421 IST");
2383
2384        let date3 = Jerusalem.with_ymd_and_hms(2005, 5, 15, 0, 0, 0).unwrap();
2385        let czc3 = ComplexZmanimCalendar {
2386            geo_location: loc.clone(),
2387            date: date3,
2388            use_elevation: UseElevation::No,
2389        };
2390        let alos3 = czc3.alos_120_minutes().unwrap().to_string();
2391        assert_eq!(alos3, "2005-05-15 03:43:01.021454229 IDT"); // off by 200 ms (?!)
2392
2393        let date4 = Jerusalem.with_ymd_and_hms(2025, 5, 15, 0, 0, 0).unwrap();
2394        let czc4 = ComplexZmanimCalendar {
2395            geo_location: loc,
2396            date: date4,
2397            use_elevation: UseElevation::No,
2398        };
2399        let alos4 = czc4.alos_120_minutes().unwrap().to_string();
2400        assert_eq!(alos4, "2025-05-15 03:42:56.506814904 IDT");
2401    }
2402
2403    #[test]
2404    fn test_tzais_72_minutes_zmanis() {
2405        let loc = GeoLocation {
2406            latitude: 31.79388,
2407            longitude: 35.03684,
2408            elevation: 586.19,
2409            timezone: Jerusalem,
2410        };
2411
2412        let date1 = Jerusalem.with_ymd_and_hms(2025, 8, 4, 0, 0, 0).unwrap();
2413        let czc1 = ComplexZmanimCalendar {
2414            geo_location: loc.clone(),
2415            date: date1,
2416            use_elevation: UseElevation::No,
2417        };
2418        let alos1 = czc1.tzais_72_minutes_zmanis().unwrap().to_string();
2419        assert_eq!(alos1, "2025-08-04 20:55:33.614725027 IDT"); // off by < 1 ms
2420
2421        let date2 = Jerusalem.with_ymd_and_hms(2025, 1, 26, 0, 0, 0).unwrap();
2422        let czc2 = ComplexZmanimCalendar {
2423            geo_location: loc.clone(),
2424            date: date2,
2425            use_elevation: UseElevation::No,
2426        };
2427        let alos2 = czc2.tzais_72_minutes_zmanis().unwrap().to_string();
2428        assert_eq!(alos2, "2025-01-26 18:11:54.813293573 IST"); // off by < 1 ms
2429
2430        let date3 = Jerusalem.with_ymd_and_hms(2005, 5, 15, 0, 0, 0).unwrap();
2431        let czc3 = ComplexZmanimCalendar {
2432            geo_location: loc.clone(),
2433            date: date3,
2434            use_elevation: UseElevation::No,
2435        };
2436        let alos3 = czc3.tzais_72_minutes_zmanis().unwrap().to_string();
2437        assert_eq!(alos3, "2005-05-15 20:52:25.429886381 IDT");
2438
2439        let date4 = Jerusalem.with_ymd_and_hms(2025, 5, 15, 0, 0, 0).unwrap();
2440        let czc4 = ComplexZmanimCalendar {
2441            geo_location: loc,
2442            date: date4,
2443            use_elevation: UseElevation::No,
2444        };
2445        let alos4 = czc4.tzais_72_minutes_zmanis().unwrap().to_string();
2446        assert_eq!(alos4, "2025-05-15 20:52:34.967135271 IDT"); // off by > 2 ms
2447    }
2448
2449    #[test]
2450    fn test_hanetz() {
2451        let loc = GeoLocation {
2452            latitude: 31.79388,
2453            longitude: 35.03684,
2454            elevation: 586.19,
2455            timezone: Jerusalem,
2456        };
2457
2458        let date1 = Jerusalem.with_ymd_and_hms(2025, 8, 4, 0, 0, 0).unwrap();
2459        let czc1 = ComplexZmanimCalendar {
2460            geo_location: loc.clone(),
2461            date: date1,
2462            use_elevation: UseElevation::HanetzShkia,
2463        };
2464        let alos1 = czc1.hanetz().unwrap().to_string();
2465        assert_eq!(alos1, "2025-08-04 05:53:38.656214524 IDT");
2466
2467        let date2 = Jerusalem.with_ymd_and_hms(2025, 1, 26, 0, 0, 0).unwrap();
2468        let czc2 = ComplexZmanimCalendar {
2469            geo_location: loc.clone(),
2470            date: date2,
2471            use_elevation: UseElevation::HanetzShkia,
2472        };
2473        let alos2 = czc2.hanetz().unwrap().to_string();
2474        assert_eq!(alos2, "2025-01-26 06:32:32.666982290 IST");
2475
2476        let date3 = Jerusalem.with_ymd_and_hms(2005, 5, 15, 0, 0, 0).unwrap();
2477        let czc3 = ComplexZmanimCalendar {
2478            geo_location: loc,
2479            date: date3,
2480            use_elevation: UseElevation::HanetzShkia,
2481        };
2482        let alos3 = czc3.hanetz().unwrap().to_string();
2483        assert_eq!(alos3, "2005-05-15 05:39:02.117825643 IDT");
2484    }
2485}