@@ -251,6 +251,16 @@ public void setUseAstronomicalChatzosForOtherZmanim(boolean useAstronomicalChatz
251251 * @see ComprehensiveZmanimCalendar#getTzaisGeonim8Point5Degrees()
252252 */
253253 protected static final double ZENITH_8_POINT_5 = GEOMETRIC_ZENITH + 8.5 ;
254+
255+ /**
256+ * The zenith of 1.583° below {@link #GEOMETRIC_ZENITH geometric zenith} (90°). This calculation is used for
257+ * calculating <em>netz amiti</em> (sunrise) and <em>shkiah amiti</em> (sunset) based on the opinion of the
258+ * <a href="https://en.wikipedia.org/wiki/Shneur_Zalman_of_Liadi">Baal Hatanya</a>.
259+ *
260+ * @see #getSunriseBaalHatanya()
261+ * @see #getSunsetBaalHatanya()
262+ */
263+ protected static final double ZENITH_1_POINT_583 = GEOMETRIC_ZENITH + 1.583 ;
254264
255265 /**
256266 * The default <em>Shabbos</em> candle lighting offset is 18 minutes. This can be changed via the
@@ -600,6 +610,107 @@ public Instant getSofZmanTfila(Instant startOfDay, Instant endOfDay, boolean syn
600610 }
601611 }
602612
613+
614+ /**
615+ * This method returns the latest time for burning <em>chametz</em> on <em>Erev Pesach</em> according to the opinion
616+ * of the <a href="https://en.wikipedia.org/wiki/Vilna_Gaon">GRA</a>. This time is 5 hours into the day based on the
617+ * opinion of the <a href="https://en.wikipedia.org/wiki/Vilna_Gaon">GRA</a> that the day is calculated from
618+ * sunrise to sunset. This returns the time 5 * {@link #getShaahZmanisGra()} after {@link #getSeaLevelSunrise() sea
619+ * level sunrise}. If it is not <em>erev Pesach</em>, a null will be returned.
620+ * @return the <code>Instant</code> of the latest time for burning <em>chametz</em> on <em>Erev Pesach</em>. If it is not
621+ * <em>erev Pesach</em> or the calculation can't be computed such as in the Arctic Circle where there is at least
622+ * one day a year where the sun does not rise, and one where it does not set, a <code>null</code> will be
623+ * returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation.
624+ * @see ZmanimCalendar#getShaahZmanisGra()
625+ * @see #getSofZmanBiurChametz(Instant, Instant, boolean)
626+ */
627+
628+ /**
629+ * A generic method for calculating <em>sof zman biur chametz</em> or the latest time one is allowed burning
630+ * <em>chametz</em> on <em>Erev Pesach</em> that is 5 * <em>shaos zmaniyos</em> (temporal hours) after the start of the
631+ * day, calculated using the start and end of the day passed to this method. If the date is not <em>erev Pesach</em>, a
632+ * null will be returned. The time from the start of day to the end of day is divided into 12 <em>shaos zmaniyos</em>
633+ * (temporal hours), and <em>sof zman biur chametz</em> is calculated as 5 of those <em>shaos zmaniyos</em> after the
634+ * beginning of the day. As an example, passing {@link #getSunrise() sunrise} and {@link #getSunset() sunset} to this
635+ * method will return <em>sof zman biur chametz</em> according to the opinion of the <a href=
636+ * "https://en.wikipedia.org/wiki/Vilna_Gaon">GRA</a>. This method's synchronous parameter indicates if the start
637+ * and end of day for the calculation are synchronous, having the same offset. This is typically the case, but some
638+ * <em>zmanim</em> calculations are based on a start and end at different offsets from the real start and end of the day,
639+ * such as starting the day at <em>alos</em> and an ending it at <em>tzais Geonim</em> or some other variant. If the day
640+ * is not synchronous a {@link #getHalfDayBasedZman(Instant, Instant, double) half-day based calculations} will be bypassed.
641+ * It would be illogical to use a half-day based calculation that start/end at <em>chatzos</em> when the two "halves" of
642+ * the day are not equal, and the halfway point between them is not at <em>chatzos</em>.
643+ *
644+ * @param startOfDay
645+ * the start of day for calculating <em>sof zman biur chametz</em>. This can be sunrise or any <em>alos</em>
646+ * passed to this method.
647+ * @param endOfDay
648+ * the end of day for calculating <em>sof zman biur chametz</em>. This can be sunset or any <em>tzais</em>
649+ * passed to this method.
650+ * @param synchronous
651+ * If the <em>zman</em> has a synchronous start and end of the day. If this is <code>false</code>, using a {@link
652+ * #isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by
653+ * definition <em>chatzos</em> will not be the middle of the day for the <em>zman</em>.
654+ * @return the <code>Instant</code> of the <em>sof zman biur chametz</em> based on the start and end of day times passed
655+ * to this method. If the date is not <em>Erev Pesach</em> or if the calculation can't be computed such as in the
656+ * Arctic Circle where there is at least one day a year where the sun does not rise, and one where it does not set,
657+ * a <code>null</code> will be returned. See detailed explanation on top of the {@link AstronomicalCalendar}
658+ * documentation.
659+ */
660+ public Instant getSofZmanBiurChametz (Instant startOfDay , Instant endOfDay , boolean synchronous ) {
661+ JewishCalendar jewishCalendar = new JewishCalendar (getLocalDate ());
662+ if (jewishCalendar .getJewishMonth () == JewishCalendar .NISSAN && jewishCalendar .getJewishDayOfMonth () == 14 ) {
663+ if (isUseAstronomicalChatzosForOtherZmanim () && synchronous ) {
664+ return getHalfDayBasedZman (startOfDay , getChatzos (), 5 );
665+ } else {
666+ return getShaahZmanisBasedZman (startOfDay , endOfDay , 5 );
667+ }
668+ } else {
669+ return null ;
670+ }
671+ }
672+
673+ /**
674+ * A generic method for calculating <em>sof zman achilas chametz</em> or the latest time one is allowed eating
675+ * <em>chametz</em> on <em>Erev Pesach</em> that is 4 * <em>shaos zmaniyos</em> (temporal hours) after the start of the
676+ * day, calculated using the start and end of the day passed to this method. If the date is not <em>erev Pesach</em>, a
677+ * null will be returned. The time from the start of day to the end of day is divided into 12 <em>shaos zmaniyos</em>
678+ * (temporal hours), and <em>sof zman achilas chametz</em> is calculated as 4 of those <em>shaos zmaniyos</em> after the
679+ * beginning of the day. As an example, passing {@link #getSunrise() sunrise} and {@link #getSunset() sunset} to this
680+ * method will return <em>sof zman achilas chametz</em> according to the opinion of the <a href=
681+ * "https://en.wikipedia.org/wiki/Vilna_Gaon">GRA</a>. This method's synchronous parameter indicates if the start
682+ * and end of day for the calculation are synchronous, having the same offset. This is typically the case, but some
683+ * <em>zmanim</em> calculations are based on a start and end at different offsets from the real start and end of the day,
684+ * such as starting the day at <em>alos</em> and an ending it at <em>tzais Geonim</em> or some other variant. If the day
685+ * is not synchronous a {@link #getHalfDayBasedZman(Instant, Instant, double) half-day based calculations} will be bypassed.
686+ * It would be illogical to use a half-day based calculation that start/end at <em>chatzos</em> when the two "halves" of
687+ * the day are not equal, and the halfway point between them is not at <em>chatzos</em>.
688+ *
689+ * @param startOfDay
690+ * the start of day for calculating <em>sof zman achilas chametz</em>. This can be sunrise or any <em>alos</em>
691+ * passed to this method.
692+ * @param endOfDay
693+ * the end of day for calculating <em>sof zman achilas chametz</em>. This can be sunset or any <em>tzais</em>
694+ * passed to this method.
695+ * @param synchronous
696+ * If the <em>zman</em> has a synchronous start and end of the day. If this is <code>false</code>, using a {@link
697+ * #isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by
698+ * definition <em>chatzos</em> will not be the middle of the day for the <em>zman</em>.
699+ * @return the <code>Instant</code> of the <em>sof zman achilas chametz</em> based on the start and end of day times passed
700+ * to this method. If the date is not <em>Erev Pesach</em> or if the calculation can't be computed such as in the
701+ * Arctic Circle where there is at least one day a year where the sun does not rise, and one where it does not set,
702+ * a <code>null</code> will be returned. See detailed explanation on top of the {@link AstronomicalCalendar}
703+ * documentation.
704+ */
705+ public Instant getSofZmanAchilasChametz (Instant startOfDay , Instant endOfDay , boolean synchronous ) {
706+ JewishCalendar jewishCalendar = new JewishCalendar (getLocalDate ());
707+ if (jewishCalendar .getJewishMonth () == JewishCalendar .NISSAN && jewishCalendar .getJewishDayOfMonth () == 14 ) {
708+ return getSofZmanTfila (startOfDay , endOfDay , synchronous );
709+ } else {
710+ return null ;
711+ }
712+ }
713+
603714 /**
604715 * A generic method for calculating the latest <em>zman tfila</em> that calls {@link #getSofZmanTfila(Instant, Instant, boolean)}
605716 * passing <code>false</code> to the synchronous parameter since there is no way to know if the start and end of the day are
@@ -1098,6 +1209,75 @@ public boolean isAssurBemlacha(Instant currentTime, Instant tzais, boolean inIsr
10981209 //is shabbos or YT and it is before tzais
10991210 return jewishCalendar .isAssurBemelacha () && currentTime .compareTo (tzais ) <= 0 ;
11001211 }
1212+
1213+ /**
1214+ * A method that returns the <a href="https://en.wikipedia.org/wiki/Shneur_Zalman_of_Liadi">Baal Hatanya</a>'s
1215+ * <em>netz amiti</em> (sunrise) without {@link AstronomicalCalculator#getElevationAdjustment(double)
1216+ * elevation adjustment}. This forms the base for the Baal Hatanya's dawn-based calculations that are
1217+ * calculated as a dip below the horizon before sunrise.
1218+ *
1219+ * According to the Baal Hatanya, <em>netz amiti</em>, or true (halachic) sunrise, is when the top of the sun's
1220+ * disk is visible at an elevation similar to the mountains of Eretz Yisrael. The time is calculated as the point at which
1221+ * the center of the sun's disk is 1.583° below the horizon. This degree-based calculation can be found in Rabbi Shalom
1222+ * DovBer Levine's commentary on The <a href="https://www.chabadlibrary.org/books/pdf/Seder-Hachnosas-Shabbos.pdf">Baal
1223+ * Hatanya's Seder Hachnasas Shabbos</a>. From an elevation of 546 meters, the top of <a href=
1224+ * "https://en.wikipedia.org/wiki/Mount_Carmel">Har Hacarmel</a>, the sun disappears when it is 1° 35' or 1.583°
1225+ * below the sea level horizon. This in turn is based on the Gemara <a href=
1226+ * "https://hebrewbooks.org/shas.aspx?mesechta=2&daf=35">Shabbos 35a</a>. There are other opinions brought down by
1227+ * Rabbi Levine, including Rabbi Yosef Yitzchok Feigelstock who calculates it as the degrees below the horizon 4 minutes after
1228+ * sunset in Yerushalayim (on the equinox). That is brought down as 1.583°. This is identical to the 1° 35' <em>zman</em>
1229+ * and is probably a typo and should be 1.683°. These calculations are used by most <a href=
1230+ * "https://en.wikipedia.org/wiki/Chabad">Chabad</a> calendars that use the Baal Hatanya's <em>zmanim</em>. See
1231+ * <a href="https://www.chabad.org/library/article_cdo/aid/3209349/jewish/About-Our-Zmanim-Calculations.htm">About Our
1232+ * <em>Zmanim</em> Calculations @ Chabad.org</a>.
1233+ *
1234+ * Note: <em>netz amiti</em> is used only for calculating certain <em>zmanim</em>, and is intentionally unpublished. For
1235+ * practical purposes, daytime <em>mitzvos</em> like <em>shofar</em> and <em>lulav</em> should not be done until after the
1236+ * published time for <em>netz</em> / sunrise.
1237+ *
1238+ * @return the <code>Instant</code> representing the exact sea level <em>netz amiti</em> (sunrise) time. If the calculation can't be
1239+ * computed such as in the Arctic Circle where there is at least one day a year where the sun does not rise, and one
1240+ * where it does not set, a <code>null</code> will be returned. See detailed explanation on top of the page.
1241+ *
1242+ * @see #getSunriseWithElevation()
1243+ * @see #getSeaLevelSunrise()
1244+ * @see #getSunsetBaalHatanya()
1245+ * @see #ZENITH_1_POINT_583
1246+ */
1247+ protected Instant getSunriseBaalHatanya () {
1248+ return getSunriseOffsetByDegrees (ZENITH_1_POINT_583 );
1249+ }
1250+
1251+ /**
1252+ * A method that returns the <a href="https://en.wikipedia.org/wiki/Shneur_Zalman_of_Liadi">Baal Hatanya</a>'s
1253+ * <em>shkiah amiti</em> (sunset) without {@link AstronomicalCalculator#getElevationAdjustment(double)
1254+ * elevation adjustment}. This forms the base for the Baal Hatanya's dusk-based calculations that are calculated
1255+ * as a dip below the horizon after sunset.
1256+ *
1257+ * According to the Baal Hatanya, <em>shkiah amiti</em>, true (<em>halachic</em>) sunset, is when the top of the
1258+ * sun's disk disappears from view at an elevation similar to the mountains of <em>Eretz Yisrael</em>.
1259+ * This time is calculated as the point at which the center of the sun's disk is 1.583 degrees below the horizon.
1260+ *
1261+ * Note: <em>shkiah amiti</em> is used only for calculating certain <em>zmanim</em>, and is intentionally unpublished. For
1262+ * practical purposes, all daytime mitzvos should be completed before the published time for <em>shkiah</em> / sunset.
1263+ *
1264+ * For further explanation of the calculations used for the Baal Hatanya's <em>zmanim</em> in this library, see
1265+ * <a href="https://www.chabad.org/library/article_cdo/aid/3209349/jewish/About-Our-Zmanim-Calculations.htm">About Our
1266+ * <em>Zmanim</em> Calculations @ Chabad.org</a>.
1267+ *
1268+ * @return the <code>Instant</code> representing the exact sea level <em>shkiah amiti</em> (sunset) time. If the calculation
1269+ * can't be computed such as in the Arctic Circle where there is at least one day a year where the sun does not
1270+ * rise, and one where it does not set, a <code>null</code> will be returned. See detailed explanation on top of
1271+ * the {@link AstronomicalCalendar} documentation.
1272+ *
1273+ * @see #getSunsetWithElevation()
1274+ * @see #getSeaLevelSunset()
1275+ * @see #getSunriseBaalHatanya()
1276+ * @see #ZENITH_1_POINT_583
1277+ */
1278+ protected Instant getSunsetBaalHatanya () {
1279+ return getSunsetOffsetByDegrees (ZENITH_1_POINT_583 );
1280+ }
11011281
11021282 /**
11031283 * A generic utility method for calculating any <em>shaah zmanis</em> (temporal hour) based <em>zman</em> with the
0 commit comments