001/* 002 * Zmanim Java API 003 * Copyright (C) 2004-2025 Eliyahu Hershfeld 004 * 005 * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General 006 * Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) 007 * any later version. 008 * 009 * This library is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied 010 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 011 * details. 012 * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to 013 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA, 014 * or connect to: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html 015 */ 016package com.kosherjava.zmanim; 017 018import java.util.Calendar; 019import java.util.Date; 020 021import com.kosherjava.zmanim.hebrewcalendar.JewishCalendar; 022import com.kosherjava.zmanim.util.AstronomicalCalculator; 023import com.kosherjava.zmanim.util.GeoLocation; 024 025/** 026 * The ZmanimCalendar is a specialized calendar that can calculate sunrise, sunset and Jewish <em>zmanim</em> 027 * (religious times) for prayers and other Jewish religious duties. This class contains the main functionality of the 028 * <em>Zmanim</em> library. For a much more extensive list of <em>zmanim</em>, use the {@link ComplexZmanimCalendar} that 029 * extends this class. See documentation for the {@link ComplexZmanimCalendar} and {@link AstronomicalCalendar} for 030 * simple examples on using the API. 031 * <strong>Elevation based <em>zmanim</em> (even sunrise and sunset) should not be used <em>lekula</em> without the guidance 032 * of a <em>posek</em></strong>. According to Rabbi Dovid Yehudah Bursztyn in his 033 * <a href="https://www.worldcat.org/oclc/1158574217">Zmanim Kehilchasam, 7th edition</a> chapter 2, section 7 (pages 181-182) 034 * and section 9 (pages 186-187), no <em>zmanim</em> besides sunrise and sunset should use elevation. However, Rabbi Yechiel 035 * Avrahom Zilber in the <a href="https://hebrewbooks.org/51654">Birur Halacha Vol. 6</a> Ch. 58 Pages 036 * <a href="https://hebrewbooks.org/pdfpager.aspx?req=51654&pgnum=42">34</a> and 037 * <a href="https://hebrewbooks.org/pdfpager.aspx?req=51654&pgnum=50">42</a> is of the opinion that elevation should be 038 * accounted for in <em>zmanim</em> calculations. Related to this, Rabbi Yaakov Karp in <a href= 039 * "https://www.worldcat.org/oclc/919472094">Shimush Zekeinim</a>, Ch. 1, page 17 states that obstructing horizons should 040 * be factored into <em>zmanim</em> calculations. The setting defaults to false (elevation will not be used for 041 * <em>zmanim</em> calculations besides sunrise and sunset), unless the setting is changed to true in {@link 042 * #setUseElevation(boolean)}. This will impact sunrise and sunset-based <em>zmanim</em> such as {@link #getSunrise()}, 043 * {@link #getSunset()}, {@link #getSofZmanShmaGRA()}, <em>alos</em>-based <em>zmanim</em> such as {@link #getSofZmanShmaMGA()} 044 * that are based on a fixed offset of sunrise or sunset and <em>zmanim</em> based on a percentage of the day such as 045 * {@link ComplexZmanimCalendar#getSofZmanShmaMGA90MinutesZmanis()} that are based on sunrise and sunset. Even when set to 046 * true it will not impact <em>zmanim</em> that are a degree-based offset of sunrise and sunset, such as {@link 047 * ComplexZmanimCalendar#getSofZmanShmaMGA16Point1Degrees()} or {@link ComplexZmanimCalendar#getSofZmanShmaBaalHatanya()} since 048 * these <em>zmanim</em> are not linked to sunrise or sunset times (the calculations are based on the astronomical definition of 049 * sunrise and sunset calculated in a vacuum with the solar radius above the horizon), and are therefore not impacted by the use 050 * of elevation. 051 * For additional information on the <em>halachic</em> impact of elevation on <em>zmanim</em> see: 052 * <ul> 053 * <li><a href="https://www.nli.org.il/en/books/NNL_ALEPH002542826/NLI">Zmanei Halacha Lema'aseh</a> 4th edition by <a href= 054 * "http://beinenu.com/rabbis/%D7%94%D7%A8%D7%91-%D7%99%D7%93%D7%99%D7%93%D7%99%D7%94-%D7%9E%D7%A0%D7%AA">Rabbi Yedidya Manat</a>. 055 * See section 1, pages 11-12 for a very concise write-up, with details in section 2, pages 37 - 63 and 133 - 151.</li> 056 * <li><a href="https://www.worldcat.org/oclc/1158574217">Zmanim Kehilchasam</a> 7th edition, by Rabbi Dovid Yehuda Burstein, vol 1, 057 * chapter 2, pages 95 - 188.</li> 058 * <li><a href="https://www.worldcat.org/oclc/36089452">Hazmanim Bahalacha</a> by Rabbi Chaim Banish , perek 7, pages 53 - 63.</li> 059 * </ul> 060 * 061 * <p><b>Note:</b> It is important to read the technical notes on top of the {@link AstronomicalCalculator} documentation 062 * before using this code. 063 * <p>I would like to thank <a href="https://www.worldcat.org/search?q=au%3AShakow%2C+Yaakov">Rabbi Yaakov Shakow</a>, the 064 * author of Luach Ikvei Hayom who spent a considerable amount of time reviewing, correcting and making suggestions on the 065 * documentation in this library. 066 * <h2>Disclaimer:</h2> I did my best to get accurate results, but please double-check before relying on these 067 * <em>zmanim</em> for <em>halacha lema'aseh</em>. 068 * 069 * @author © Eliyahu Hershfeld 2004 - 2025 070 */ 071public class ZmanimCalendar extends AstronomicalCalendar { 072 073 /** 074 * Is elevation factored in for some <em>zmanim</em> (see {@link #isUseElevation()} for additional information). 075 * @see #isUseElevation() 076 * @see #setUseElevation(boolean) 077 */ 078 private boolean useElevation; 079 080 /** 081 * Is elevation above sea level calculated for times besides sunrise and sunset. According to Rabbi Dovid Yehuda 082 * Bursztyn in his <a href="https://www.worldcat.org/oclc/659793988">Zmanim Kehilchasam (second edition published 083 * in 2007)</a> chapter 2 (pages 186-187) no <em>zmanim</em> besides sunrise and sunset should use elevation. However, 084 * Rabbi Yechiel Avrahom Zilber in the <a href="https://hebrewbooks.org/51654">Birur Halacha Vol. 6</a> Ch. 58 Pages 085 * <a href="https://hebrewbooks.org/pdfpager.aspx?req=51654&pgnum=42">34</a> and <a href= 086 * "https://hebrewbooks.org/pdfpager.aspx?req=51654&pgnum=50">42</a> is of the opinion that elevation should be 087 * accounted for in <em>zmanim</em> calculations. Related to this, Rabbi Yaakov Karp in <a href= 088 * "https://www.worldcat.org/oclc/919472094">Shimush Zekeinim</a>, Ch. 1, page 17 states that obstructing horizons 089 * should be factored into <em>zmanim</em> calculations.The setting defaults to false (elevation will not be used for 090 * <em>zmanim</em> calculations), unless the setting is changed to true in {@link #setUseElevation(boolean)}. This will 091 * impact sunrise and sunset based <em>zmanim</em> such as {@link #getSunrise()}, {@link #getSunset()}, 092 * {@link #getSofZmanShmaGRA()}, alos based <em>zmanim</em> such as {@link #getSofZmanShmaMGA()} that are based on a 093 * fixed offset of sunrise or sunset and <em>zmanim</em> based on a percentage of the day such as {@link 094 * ComplexZmanimCalendar#getSofZmanShmaMGA90MinutesZmanis()} that are based on sunrise and sunset. It will not impact 095 * <em>zmanim</em> that are a degree based offset of sunrise and sunset, such as 096 * {@link ComplexZmanimCalendar#getSofZmanShmaMGA16Point1Degrees()} or {@link ComplexZmanimCalendar#getSofZmanShmaBaalHatanya()}. 097 * 098 * @return if the use of elevation is active 099 * 100 * @see #setUseElevation(boolean) 101 */ 102 public boolean isUseElevation() { 103 return useElevation; 104 } 105 106 /** 107 * Sets whether elevation above sea level is factored into <em>zmanim</em> calculations for times besides sunrise and sunset. 108 * See {@link #isUseElevation()} for more details. 109 * @see #isUseElevation() 110 * 111 * @param useElevation set to true to use elevation in <em>zmanim</em> calculations 112 */ 113 public void setUseElevation(boolean useElevation) { 114 this.useElevation = useElevation; 115 } 116 117 /** 118 * Is astronomical <em>chatzos</em> used for <em>zmanim</em> calculations. The default value of <code>true</code> will 119 * keep the standard astronomical <em>chatzos</em> calculation, while setting it to <code>false</code> will use half of 120 * a solar day calculation for <em>chatzos</em>. 121 * @see #isUseAstronomicalChatzos() 122 * @see #setUseAstronomicalChatzos(boolean) 123 * @see #getChatzos() 124 * @see #getSunTransit() 125 * @see #getChatzosAsHalfDay() 126 * @see #useAstronomicalChatzosForOtherZmanim 127 */ 128 private boolean useAstronomicalChatzos = true; 129 130 /** 131 * Is {@link #getSunTransit() astronomical <em>chatzos</em>} used for {@link #getChatzos()} for enhanced accuracy. For 132 * example as the day lengthens, the second half of the day is longer than the first and astronomical <em>chatzos</em> 133 * would be a drop earlier than half of the time between sunrise and sunset. 134 * 135 * @todo In the future, if this is set to true, the following may change to enhance accuracy. {@link #getSofZmanShmaGRA() 136 * <em>Sof zman Shma</em> GRA} would be calculated as 3 <em>shaos zmaniyos</em> after sunrise, but the <em>shaos 137 * zmaniyos</em> would be calculated a a 6th of the time between sunrise and <em>chatzos</em>, as opposed to a 12th of the 138 * time between sunrise and sunset. {@link #getMinchaGedola() <em>mincha gedola</em>} will be calculated as half a 139 * <em>shaah zmanis</em> of afternoon hours (a 6th of the time between <em>chatzos</em> and sunset after astronomical 140 * <em>chatzos</em> as opposed to 6.5 <em>shaos zmaniyos</em> after sunrise. {@link #getPlagHamincha() <em>Plag 141 * hamincha</em>} would be calculated as 4.75 <em>shaos zmaniyos</em> after astronomical <em>chatzos</em> as opposed to 10.75 142 * <em>shaos zmaniyos</em> after sunrise. Etc. 143 * 144 * @return if the use of astronomical <em>chatzos</em> is active. 145 * @see #useAstronomicalChatzos 146 * @see #setUseAstronomicalChatzos(boolean) 147 * @see #getChatzos() 148 * @see #getSunTransit() 149 * @see #getChatzosAsHalfDay() 150 * @see #isUseAstronomicalChatzosForOtherZmanim() 151 */ 152 public boolean isUseAstronomicalChatzos() { 153 return useAstronomicalChatzos; 154 } 155 156 /** 157 * Sets if astronomical <em>chatzos</em> should be used in calculations of other <em>zmanim</em> for enhanced accuracy. 158 * @param useAstronomicalChatzos set to true to use astronomical in <em>chatzos</em> in <em>zmanim</em> calculations. 159 * @see #useAstronomicalChatzos 160 * @see #isUseAstronomicalChatzos() 161 * @see #getChatzos() 162 * @see #getSunTransit() 163 * @see #getChatzosAsHalfDay() 164 * @see #setUseAstronomicalChatzosForOtherZmanim(boolean) 165 */ 166 public void setUseAstronomicalChatzos(boolean useAstronomicalChatzos) { 167 this.useAstronomicalChatzos = useAstronomicalChatzos; 168 } 169 170 /** 171 * Is astronomical <em>chatzos</em> used for <em>zmanim</em> calculations besides <em>chatzos</em> itself for enhanced 172 * accuracy. The default value of <code>false</code> will keep the standard start to end of day calculations, while setting 173 * it to <code>true</code> will use half of a solar day calculation for <em>zmanim</em>. 174 * @see #isUseAstronomicalChatzosForOtherZmanim() 175 * @see #setUseAstronomicalChatzosForOtherZmanim(boolean) 176 * @see #isUseAstronomicalChatzos() 177 * @see #setUseAstronomicalChatzos(boolean) 178 * @see #getChatzos() 179 */ 180 private boolean useAstronomicalChatzosForOtherZmanim = false; 181 182 /** 183 * Is astronomical <em>chatzos</em> used for <em>zmanim</em> calculations besides <em>chatzos</em> itself for enhanced 184 * accuracy. For example as the day is lengthening (as we approach spring season), the second half of the day is longer than 185 * the first and astronomical <em>chatzos</em> would be a drop earlier than half of the time between sunrise and sunset. 186 * Conversely, the second half of the day would be shorter in the autumn as the days start getting shorter. 187 * 188 * @todo In the future, if this is set to true, the following may change to enhance accuracy. {@link #getSofZmanShmaGRA() 189 * <em>Sof zman Shma</em> GRA} would be calculated as 3 <em>shaos zmaniyos</em> after sunrise, but the <em>shaos 190 * zmaniyos</em> would be calculated a a 6th of the time between sunrise and <em>chatzos</em>, as opposed to a 12th of the 191 * time between sunrise and sunset. {@link #getMinchaGedola() <em>mincha gedola</em>} will be calculated as half a 192 * <em>shaah zmanis</em> of afternoon hours (a 6th of the time between <em>chatzos</em> and sunset after astronomical 193 * <em>chatzos</em> as opposed to 6.5 <em>shaos zmaniyos</em> after sunrise. {@link #getPlagHamincha() <em>Plag 194 * hamincha</em>} would be calculated as 4.75 <em>shaos zmaniyos</em> after astronomical <em>chatzos</em> as opposed to 10.75 195 * <em>shaos zmaniyos</em> after sunrise. Etc. 196 * 197 * @return if the use of astronomical <em>chatzos</em> is active. 198 * @see #useAstronomicalChatzosForOtherZmanim 199 * @see #setUseAstronomicalChatzosForOtherZmanim(boolean) 200 * @see #useAstronomicalChatzos 201 * @see #setUseAstronomicalChatzos(boolean) 202 */ 203 public boolean isUseAstronomicalChatzosForOtherZmanim() { 204 return useAstronomicalChatzosForOtherZmanim; 205 } 206 207 /** 208 * Sets if astronomical <em>chatzos</em> should be used in calculations of other <em>zmanim</em> for enhanced accuracy. 209 * @param useAstronomicalChatzosForOtherZmanim set to true to use astronomical in <em>chatzos</em> in <em>zmanim</em> calculations. 210 * @see #useAstronomicalChatzos 211 * @see #isUseAstronomicalChatzos() 212 */ 213 public void setUseAstronomicalChatzosForOtherZmanim(boolean useAstronomicalChatzosForOtherZmanim) { 214 this.useAstronomicalChatzosForOtherZmanim = useAstronomicalChatzosForOtherZmanim; 215 } 216 217 /** 218 * The zenith of 16.1° below geometric zenith (90°). This calculation is used for determining <em>alos</em> 219 * (dawn) and <em>tzais</em> (nightfall) in some opinions. It is based on the calculation that the time between dawn 220 * and sunrise (and sunset to nightfall) is 72 minutes, the time that is takes to walk 4 <a href= 221 * "https://en.wikipedia.org/wiki/Biblical_and_Talmudic_units_of_measurement">mil</a> at 18 minutes a mil (<a href= 222 * "https://en.wikipedia.org/wiki/Maimonides">Rambam</a> and others). The sun's position below the horizon 72 minutes 223 * before {@link #getSunrise() sunrise} in Jerusalem <a href= 224 * "https://kosherjava.com/2022/01/12/equinox-vs-equilux-zmanim-calculations/">around the equinox / equilux</a> is 225 * 16.1° below {@link #GEOMETRIC_ZENITH geometric zenith}. 226 * 227 * @see #getAlosHashachar() 228 * @see ComplexZmanimCalendar#getAlos16Point1Degrees() 229 * @see ComplexZmanimCalendar#getTzais16Point1Degrees() 230 * @see ComplexZmanimCalendar#getSofZmanShmaMGA16Point1Degrees() 231 * @see ComplexZmanimCalendar#getSofZmanTfilaMGA16Point1Degrees() 232 * @see ComplexZmanimCalendar#getMinchaGedola16Point1Degrees() 233 * @see ComplexZmanimCalendar#getMinchaKetana16Point1Degrees() 234 * @see ComplexZmanimCalendar#getPlagHamincha16Point1Degrees() 235 * @see ComplexZmanimCalendar#getPlagAlos16Point1ToTzaisGeonim7Point083Degrees() 236 * @see ComplexZmanimCalendar#getSofZmanShmaAlos16Point1ToSunset() 237 */ 238 protected static final double ZENITH_16_POINT_1 = GEOMETRIC_ZENITH + 16.1; 239 240 /** 241 * The zenith of 8.5° below geometric zenith (90°). This calculation is used for calculating <em>alos</em> 242 * (dawn) and <em>tzais</em> (nightfall) in some opinions. This calculation is based on the sun's position below the 243 * horizon 36 minutes after {@link #getSunset() sunset} in Jerusalem <a href= 244 * "https://kosherjava.com/2022/01/12/equinox-vs-equilux-zmanim-calculations/">around the equinox / equilux</a>, which 245 * is 8.5° below {@link #GEOMETRIC_ZENITH geometric zenith}. The <em><a href= 246 * "https://www.worldcat.org/oclc/29283612">Ohr Meir</a></em> considers this the time that 3 small stars are visible, 247 * which is later than the required 3 medium stars. 248 * 249 * @see #getTzais() 250 * @see ComplexZmanimCalendar#getTzaisGeonim8Point5Degrees() 251 */ 252 protected static final double ZENITH_8_POINT_5 = GEOMETRIC_ZENITH + 8.5; 253 254 /** 255 * The default <em>Shabbos</em> candle lighting offset is 18 minutes. This can be changed via the 256 * {@link #setCandleLightingOffset(double)} and retrieved by the {@link #getCandleLightingOffset()}. 257 */ 258 private double candleLightingOffset = 18; 259 260 /** 261 * This method will return {@link #getSeaLevelSunrise() sea level sunrise} if {@link #isUseElevation()} is false (the 262 * default), or elevation adjusted {@link AstronomicalCalendar#getSunrise()} if it is true. This allows relevant <em>zmanim</em> 263 * in this and extending classes (such as the {@link ComplexZmanimCalendar}) to automatically adjust to the elevation setting. 264 * 265 * @return {@link #getSeaLevelSunrise()} if {@link #isUseElevation()} is false (the default), or elevation adjusted 266 * {@link AstronomicalCalendar#getSunrise()} if it is true. 267 * @see com.kosherjava.zmanim.AstronomicalCalendar#getSunrise() 268 */ 269 protected Date getElevationAdjustedSunrise() { 270 if (isUseElevation()) { 271 return super.getSunrise(); 272 } 273 return getSeaLevelSunrise(); 274 } 275 276 /** 277 * This method will return {@link #getSeaLevelSunrise() sea level sunrise} if {@link #isUseElevation()} is false (the default), 278 * or elevation adjusted {@link AstronomicalCalendar#getSunrise()} if it is true. This allows relevant <em>zmanim</em> 279 * in this and extending classes (such as the {@link ComplexZmanimCalendar}) to automatically adjust to the elevation setting. 280 * 281 * @return {@link #getSeaLevelSunset()} if {@link #isUseElevation()} is false (the default), or elevation adjusted 282 * {@link AstronomicalCalendar#getSunset()} if it is true. 283 * @see com.kosherjava.zmanim.AstronomicalCalendar#getSunset() 284 */ 285 protected Date getElevationAdjustedSunset() { 286 if (isUseElevation()) { 287 return super.getSunset(); 288 } 289 return getSeaLevelSunset(); 290 } 291 292 /** 293 * A method that returns <em>tzais</em> (nightfall) when the sun is {@link #ZENITH_8_POINT_5 8.5°} below the 294 * {@link #GEOMETRIC_ZENITH geometric horizon} (90°) after {@link #getSunset() sunset}, a time that Rabbi Meir 295 * Posen in his the <em><a href="https://www.worldcat.org/oclc/29283612">Ohr Meir</a></em> calculated that 3 small 296 * stars are visible, which is later than the required 3 medium stars. See the {@link #ZENITH_8_POINT_5} constant. 297 * 298 * @see #ZENITH_8_POINT_5 299 * 300 * @return The <code>Date</code> of nightfall. If the calculation can't be computed such as northern and southern 301 * locations even south of the Arctic Circle and north of the Antarctic Circle where the sun may not reach 302 * low enough below the horizon for this calculation, a <code>null</code> will be returned. See detailed 303 * explanation on top of the {@link AstronomicalCalendar} documentation. 304 * @see #ZENITH_8_POINT_5 305 * ComplexZmanimCalendar#getTzaisGeonim8Point5Degrees() that returns an identical time to this generic <em>tzais</em> 306 */ 307 public Date getTzais() { 308 return getSunsetOffsetByDegrees(ZENITH_8_POINT_5); 309 } 310 311 /** 312 * Returns <em>alos</em> (dawn) based on the time when the sun is {@link #ZENITH_16_POINT_1 16.1°} below the 313 * eastern {@link #GEOMETRIC_ZENITH geometric horizon} before {@link #getSunrise() sunrise}. This is based on the 314 * calculation that the time between dawn and sunrise (and sunset to nightfall) is 72 minutes, the time that is 315 * takes to walk 4 <a href="https://en.wikipedia.org/wiki/Biblical_and_Talmudic_units_of_measurement">mil</a> at 316 * 18 minutes a mil (<a href="https://en.wikipedia.org/wiki/Maimonides">Rambam</a> and others). The sun's position 317 * below the horizon 72 minutes before {@link #getSunrise() sunrise} in Jerusalem on the <a href= 318 * "https://kosherjava.com/2022/01/12/equinox-vs-equilux-zmanim-calculations/">around the equinox / equilux</a> is 319 * 16.1° below {@link #GEOMETRIC_ZENITH}. 320 * 321 * @see #ZENITH_16_POINT_1 322 * @see ComplexZmanimCalendar#getAlos16Point1Degrees() 323 * 324 * @return The <code>Date</code> of dawn. If the calculation can't be computed such as northern and southern 325 * locations even south of the Arctic Circle and north of the Antarctic Circle where the sun may not reach 326 * low enough below the horizon for this calculation, a <code>null</code> will be returned. See detailed 327 * explanation on top of the {@link AstronomicalCalendar} documentation. 328 */ 329 public Date getAlosHashachar() { 330 return getSunriseOffsetByDegrees(ZENITH_16_POINT_1); 331 } 332 333 /** 334 * Method to return <em>alos</em> (dawn) calculated as 72 minutes before {@link #getSunrise() sunrise} or 335 * {@link #getSeaLevelSunrise() sea level sunrise} (depending on the {@link #isUseElevation()} setting). This time 336 * is based on the time to walk the distance of 4 <a href= 337 * "https://en.wikipedia.org/wiki/Biblical_and_Talmudic_units_of_measurement">mil</a> at 18 minutes a mil. The 338 * 72-minute time (but not the concept of fixed minutes) is based on the opinion that the time of the <em>Neshef</em> 339 * (twilight between dawn and sunrise) does not vary by the time of year or location but depends on the time it takes 340 * to walk the distance of 4 mil. 341 * 342 * @return the <code>Date</code> representing the time. If the calculation can't be computed such as in the Arctic 343 * Circle where there is at least one day a year where the sun does not rise, and one where it does not set, 344 * a <code>null</code> will be returned. See detailed explanation on top of the {@link AstronomicalCalendar} 345 * documentation. 346 */ 347 public Date getAlos72() { 348 return getTimeOffset(getElevationAdjustedSunrise(), -72 * MINUTE_MILLIS); 349 } 350 351 /** 352 * This method returns {@link #getSunTransit() Astronomical <em>chatzos</em>} if the 353 * {@link com.kosherjava.zmanim.util.AstronomicalCalculator calculator} class used supports it and 354 * {@link #isUseAstronomicalChatzos() isUseAstronomicalChatzos()} is set to <em>true</em> or the {@link #getChatzosAsHalfDay() 355 * halfway point between sunrise and sunset} if it does not support it, or it is not configured to use it. There are currently 356 * two {@link com.kosherjava.zmanim.util.AstronomicalCalculator calculators} available in the API, the default {@link 357 * com.kosherjava.zmanim.util.NOAACalculator NOAA calculator} and the {@link com.kosherjava.zmanim.util.SunTimesCalculator USNO 358 * calculator}. The USNO calculator calculates <em>chatzos</em> as halfway between sunrise and sunset (identical to six <em>shaos 359 * zmaniyos</em> after sunrise), while the NOAACalculator calculates it more accurately as {@link #getSunTransit() astronomical 360 * <em>chatzos</em>}. See <a href="https://kosherjava.com/2020/07/02/definition-of-chatzos/">The Definition of <em>Chatzos</em></a> 361 * for a detailed explanation of the ways to calculate <em>Chatzos</em>. Since half-day <em>chatzos</em> can be <code>null</code> in 362 * the Arctic on a day when either sunrise or sunset did not happen and astronomical <em>chatzos</em> can be calculated even in the 363 * Arctic, if half-day <em>chatzos</em> calculates as <code>null</code> and astronomical <em>chatzos</em> is supported by the 364 * calculator, astronomical <em>chatzos</em> will be returned to avoid returning a <code>null</code>. 365 * 366 * @see AstronomicalCalendar#getSunTransit() 367 * @see #getChatzosAsHalfDay() 368 * @see #isUseAstronomicalChatzos() 369 * @see #setUseAstronomicalChatzos(boolean) 370 * @return the <code>Date</code> of <em>chatzos</em>. If the calculation can't be computed such as in the Arctic Circle 371 * where there is at least one day where the sun does not rise, and one where it does not set, and the calculator does not 372 * support astronomical calculations (that will never report a <code>null</code>) a <code>null</code> will be returned. 373 * See detailed explanation on top of the {@link AstronomicalCalendar} documentation. 374 */ 375 public Date getChatzos() { 376 if (useAstronomicalChatzos) { 377 return getSunTransit(); // can be null of the calculator does not support astronomical chatzos 378 } else { 379 Date halfDayChatzos = getChatzosAsHalfDay(); 380 if (halfDayChatzos == null) { 381 return getSunTransit(); // can be null if the calculator does not support astronomical chatzos 382 } else { 383 return halfDayChatzos; 384 } 385 } 386 } 387 388 /** 389 * Returns <em>chatzos</em> calculated as halfway between sunrise and sunset. Many are of the opinion that 390 * <em>chatzos</em> is calculated as the midpoint between {@link #getSeaLevelSunrise() sea level sunrise} and 391 * {@link #getSeaLevelSunset() sea level sunset}, despite it not being the most accurate way to calculate it. A day 392 * starting at <em>alos</em> and ending at <em>tzais</em> using the same time or degree offset will also return 393 * the same time. In reality due to lengthening or shortening of day, this is not necessarily the exact midpoint of 394 * the day, but it is very close. This method allows you to use the NOAACalculator and still calculate <em>chatzos 395 * </em> as six <em>shaos zmaniyos</em> after sunrise. There are currently two {@link 396 * com.kosherjava.zmanim.util.AstronomicalCalculator calculators} available in the API, the {@link 397 * com.kosherjava.zmanim.util.NOAACalculator} and the {@link com.kosherjava.zmanim.util.SunTimesCalculator}. 398 * The SunTimesCalculator calculates <em>chatzos</em> as halfway between sunrise and sunset (and of six <em>shaos 399 * zmaniyos</em>), while the NOAACalculator calculates it as astronomical <em>chatzos</em> that is slightly more 400 * accurate. This method allows you to use the NOAACalculator and still calculate <em>chatzos</em> as six <em>shaos 401 * zmaniyos</em> after sunrise. See <a href="https://kosherjava.com/2020/07/02/definition-of-chatzos/">The Definition 402 * of <em>Chatzos</em></a> for a detailed explanation of the ways to calculate <em>Chatzos</em>. 403 * 404 * @see com.kosherjava.zmanim.util.NOAACalculator#getUTCNoon(Calendar, GeoLocation) 405 * @see com.kosherjava.zmanim.util.SunTimesCalculator#getUTCNoon(Calendar, GeoLocation) 406 * @see com.kosherjava.zmanim.util.AstronomicalCalculator#getUTCNoon(Calendar, GeoLocation) 407 * @see AstronomicalCalendar#getSunTransit(Date, Date) 408 * @see #getChatzos() 409 * @see #getSunTransit() 410 * @see #isUseAstronomicalChatzos() 411 * 412 * @return the <code>Date</code> of the latest <em>chatzos</em>. If the calculation can't be computed such 413 * as in the Arctic Circle where there is at least one day a year where the sun does not rise, and one where 414 * it does not set, a <code>null</code> will be returned. See detailed explanation on top of the 415 * {@link AstronomicalCalendar} documentation. 416 */ 417 public Date getChatzosAsHalfDay() { 418 return getSunTransit(getSeaLevelSunrise(), getSeaLevelSunset()); 419 } 420 421 /** 422 * A generic method for calculating the latest <em>zman krias shema</em> (time to recite shema in the morning) that is 3 * 423 * <em>shaos zmaniyos</em> (temporal hours) after the start of the day, calculated using the start and end of the day passed 424 * to this method. The time from the start of day to the end of day are divided into 12 <em>shaos zmaniyos</em> (temporal 425 * hours), and the latest <em>zman krias shema</em> is calculated as 3 of those <em>shaos zmaniyos</em> after the beginning of 426 * the day. If {@link #isUseAstronomicalChatzosForOtherZmanim()} is <code>true</code>, the 3 <em>shaos zmaniyos</em> will be 427 * based on 1/6 of the time between sunrise and {@link #getSunTransit() astronomical <em>chatzos</em>}. As an example, passing 428 * {@link #getSunrise() sunrise} and {@link #getSunset() sunset} or {@link #getSeaLevelSunrise() sea level sunrise} and {@link 429 * #getSeaLevelSunset() sea level sunset} to this method (or {@link #getElevationAdjustedSunrise()} and {@link 430 * #getElevationAdjustedSunset()} that is driven off the {@link #isUseElevation()} setting) will return <em>sof zman krias 431 * shema</em> according to the opinion of the <a href="https://en.wikipedia.org/wiki/Vilna_Gaon">GRA</a>. In cases 432 * where the start and end dates are not synchronous such as in {@link ComplexZmanimCalendar 433 * #getSofZmanShmaAlos16Point1ToTzaisGeonim7Point083Degrees()} <code>false</code> should be passed to the synchronous parameter 434 * to ensure that {@link #isUseAstronomicalChatzosForOtherZmanim()} will not be used. 435 * 436 * @param startOfDay 437 * the start of day for calculating <em>zman krias shema</em>. This can be sunrise or any <em>alos</em> passed 438 * to this method. 439 * @param endOfDay 440 * the end of day for calculating <em>zman krias shema</em>. This can be sunset or any <em>tzais</em> passed to 441 * this method. 442 * @param synchronous 443 * If the <em>zman</em> has a synchronous start and end of the day. If this is <code>false</code>, using a {@link 444 * #isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by 445 * definition <em>chatzos</em> will not be the middle of the day for the <em>zman</em>. 446 * @see #isUseAstronomicalChatzosForOtherZmanim() 447 * @return the <code>Date</code> of the latest <em>zman shema</em> based on the start and end of day times passed to this 448 * method. If the calculation can't be computed such as in the Arctic Circle where there is at least one day 449 * a year where the sun does not rise, and one where it does not set, a <code>null</code> will be returned. See 450 * detailed explanation on top of the {@link AstronomicalCalendar} documentation. 451 */ 452 public Date getSofZmanShma(Date startOfDay, Date endOfDay, boolean synchronous) { 453 if (isUseAstronomicalChatzosForOtherZmanim() && synchronous) { 454 return getHalfDayBasedZman(startOfDay, getChatzos(), 3); 455 } else { 456 return getShaahZmanisBasedZman(startOfDay, endOfDay, 3); 457 } 458 } 459 460 /** 461 * A generic method for calculating the latest <em>zman krias shema</em> that calls {@link #getSofZmanShma(Date, Date, boolean)} 462 * passing <code>false</code> to the synchronous parameter since there is no way to know if the start and end of the day are 463 * synchronous. Passing true when they are not synchronous is too much of a risk. See information on that method for more details. 464 * @param startOfDay 465 * the start of day for calculating <em>zman krias shema</em>. This can be sunrise or any <em>alos</em> passed 466 * to this method. 467 * @param endOfDay 468 * the end of day for calculating <em>zman krias shema</em>. This can be sunset or any <em>tzais</em> passed to 469 * this method. 470 * @return the <code>Date</code> of the latest <em>zman shema</em> based on the start and end of day times passed to this 471 * method. If the calculation can't be computed such as in the Arctic Circle where there is at least one day 472 * a year where the sun does not rise, and one where it does not set, a <code>null</code> will be returned. See 473 * detailed explanation on top of the {@link AstronomicalCalendar} documentation. 474 * @see #getSofZmanShma(Date, Date, boolean) 475 */ 476 public Date getSofZmanShma(Date startOfDay, Date endOfDay) { 477 return getSofZmanShma(startOfDay, endOfDay, false); 478 } 479 480 /** 481 * This method returns the latest <em>zman krias shema</em> (time to recite shema in the morning) that is 3 * 482 * {@link #getShaahZmanisGra() <em>shaos zmaniyos</em>} (solar hours) after {@link #getSunrise() sunrise} or 483 * {@link #getSeaLevelSunrise() sea level sunrise} (depending on the {@link #isUseElevation()} setting), according 484 * to the <a href="https://en.wikipedia.org/wiki/Vilna_Gaon">GRA</a>. 485 * The day is calculated from {@link #getSeaLevelSunrise() sea level sunrise} to {@link #getSeaLevelSunset() sea level 486 * sunset} or from {@link #getSunrise() sunrise} to {@link #getSunset() sunset} (depending on the 487 * {@link #isUseElevation()} setting). 488 * 489 * @see #getSofZmanShma(Date, Date) 490 * @see #getShaahZmanisGra() 491 * @see #isUseElevation() 492 * @see ComplexZmanimCalendar#getSofZmanShmaBaalHatanya() 493 * @return the <code>Date</code> of the latest <em>zman shema</em> according to the GRA. If the calculation can't be 494 * computed such as in the Arctic Circle where there is at least one day a year where the sun does not rise, 495 * and one where it does not set, a <code>null</code> will be returned. See the detailed explanation on top 496 * of the {@link AstronomicalCalendar} documentation. 497 */ 498 public Date getSofZmanShmaGRA() { 499 return getSofZmanShma(getElevationAdjustedSunrise(), getElevationAdjustedSunset(), true); 500 } 501 502 /** 503 * This method returns the latest <em>zman krias shema</em> (time to recite shema in the morning) that is 3 * 504 * {@link #getShaahZmanisMGA() <em>shaos zmaniyos</em>} (solar hours) after {@link #getAlos72()}, according to the 505 * <a href="https://en.wikipedia.org/wiki/Avraham_Gombiner">Magen Avraham (MGA)</a>. The day is calculated 506 * from 72 minutes before {@link #getSeaLevelSunrise() sea level sunrise} to 72 minutes after {@link 507 * #getSeaLevelSunset() sea level sunset} or from 72 minutes before {@link #getSunrise() sunrise} to {@link #getSunset() 508 * sunset} (depending on the {@link #isUseElevation()} setting). 509 * 510 * @return the <code>Date</code> of the latest <em>zman shema</em>. If the calculation can't be computed such as in 511 * the Arctic Circle where there is at least one day a year where the sun does not rise, and one where it 512 * does not set, a <code>null</code> will be returned. See detailed explanation on top of the 513 * {@link AstronomicalCalendar} documentation. 514 * @see #getSofZmanShma(Date, Date) 515 * @see ComplexZmanimCalendar#getShaahZmanis72Minutes() 516 * @see ComplexZmanimCalendar#getAlos72() 517 * @see ComplexZmanimCalendar#getSofZmanShmaMGA72Minutes() that 518 */ 519 public Date getSofZmanShmaMGA() { 520 return getSofZmanShma(getAlos72(), getTzais72(), true); 521 } 522 523 /** 524 * This method returns the <em>tzais</em> (nightfall) based on the opinion of <em>Rabbeinu Tam</em> that 525 * <em>tzais hakochavim</em> is calculated as 72 minutes after sunset, the time it takes to walk 4 <a href= 526 * "https://en.wikipedia.org/wiki/Biblical_and_Talmudic_units_of_measurement">mil</a> at 18 minutes a mil. 527 * According to the <a href="https://en.wikipedia.org/wiki/Samuel_Loew">Machtzis Hashekel</a> in Orach Chaim 528 * 235:3, the <a href="https://en.wikipedia.org/wiki/Joseph_ben_Meir_Teomim">Pri Megadim</a> in Orach 529 * Chaim 261:2 (see the Biur Halacha) and others (see Hazmanim Bahalacha 17:3 and 17:5) the 72 minutes are standard 530 * clock minutes any time of the year in any location. Depending on the {@link #isUseElevation()} setting, a 72-minute 531 * offset from either {@link #getSunset() sunset} or {@link #getSeaLevelSunset() sea level sunset} is used. 532 * 533 * @see ComplexZmanimCalendar#getTzais16Point1Degrees() 534 * @return the <code>Date</code> representing 72 minutes after sunset. If the calculation can't be 535 * computed such as in the Arctic Circle where there is at least one day a year where the sun does not rise, 536 * and one where it does not set, a <code>null</code> will be returned See detailed explanation on top of the 537 * {@link AstronomicalCalendar} documentation. 538 */ 539 public Date getTzais72() { 540 return getTimeOffset(getElevationAdjustedSunset(), 72 * MINUTE_MILLIS); 541 } 542 543 /** 544 * A method to return candle lighting time, calculated as {@link #getCandleLightingOffset()} minutes before 545 * {@link #getSeaLevelSunset() sea level sunset}. This will return the time for any day of the week, since it can be 546 * used to calculate candle lighting time for <em>Yom Tov</em> (mid-week holidays) as well. Elevation adjustments 547 * are intentionally not performed by this method, but you can calculate it by passing the elevation adjusted sunset 548 * to {@link #getTimeOffset(Date, long)}. 549 * 550 * @return candle lighting time. If the calculation can't be computed such as in the Arctic Circle where there is at 551 * least one day a year where the sun does not rise, and one where it does not set, a <code>null</code> will 552 * be returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. 553 * 554 * @see #getSeaLevelSunset() 555 * @see #getCandleLightingOffset() 556 * @see #setCandleLightingOffset(double) 557 */ 558 public Date getCandleLighting() { 559 return getTimeOffset(getSeaLevelSunset(), -getCandleLightingOffset() * MINUTE_MILLIS); 560 } 561 562 /** 563 * A generic method for calculating the latest <em>zman tfilah</em> (time to recite the morning prayers) 564 * that is 4 * <em>shaos zmaniyos</em> (temporal hours) after the start of the day, calculated using the start and 565 * end of the day passed to this method. 566 * The time from the start of day to the end of day are divided into 12 <em>shaos zmaniyos</em> (temporal hours), 567 * and <em>sof zman tfila</em> is calculated as 4 of those <em>shaos zmaniyos</em> after the beginning of the day. 568 * As an example, passing {@link #getSunrise() sunrise} and {@link #getSunset() sunset} or {@link #getSeaLevelSunrise() 569 * sea level sunrise} and {@link #getSeaLevelSunset() sea level sunset} (depending on the {@link #isUseElevation()} 570 * elevation setting) to this method will return <em>zman tfilah</em> according to the opinion of the <a href= 571 * "https://en.wikipedia.org/wiki/Vilna_Gaon">GRA</a>. This method's synchronous parameter indicates if the start 572 * and end of day for the calculation are synchronous, having the same offset. This is typically the case, but some 573 * <em>zmanim</em> calculations are based on a start and end at different offsets from the real start and end of the day, 574 * 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 575 * is not synchronous a {@link #getHalfDayBasedZman(Date, Date, double) half-day based calculations} will be bypassed. 576 * It would be illogical to use a half-day based calculation that start/end at <em>chatzos</em> when the two "halves" of 577 * the day are not equal, and the halfway point between them is not at <em>chatzos</em>. 578 * 579 * @param startOfDay 580 * the start of day for calculating <em>zman tfilah</em>. This can be sunrise or any <em>alos</em> passed 581 * to this method. 582 * @param endOfDay 583 * the end of day for calculating <em>zman tfilah</em>. This can be sunset or any <em>tzais</em> passed 584 * to this method. 585 * @param synchronous 586 * If the <em>zman</em> has a synchronous start and end of the day. If this is <code>false</code>, using a {@link 587 * #isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by 588 * definition <em>chatzos</em> will not be the middle of the day for the <em>zman</em>. 589 * @return the <code>Date</code> of the latest <em>zman tfilah</em> based on the start and end of day times passed 590 * to this method. If the calculation can't be computed such as in the Arctic Circle where there is at least 591 * one day a year where the sun does not rise, and one where it does not set, a <code>null</code> will be 592 * returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. 593 */ 594 public Date getSofZmanTfila(Date startOfDay, Date endOfDay, boolean synchronous) { 595 if (isUseAstronomicalChatzosForOtherZmanim() && synchronous) { 596 return getHalfDayBasedZman(startOfDay, getChatzos(), 4); 597 } else { 598 return getShaahZmanisBasedZman(startOfDay, endOfDay, 4); 599 } 600 } 601 602 /** 603 * A generic method for calculating the latest <em>zman tfila</em> that calls {@link #getSofZmanTfila(Date, Date, boolean)} 604 * passing <code>false</code> to the synchronous parameter since there is no way to know if the start and end of the day are 605 * synchronous. Passing true when they are not synchronous is too much of a risk. See information on that method for more details. 606 * @param startOfDay 607 * the start of day for calculating <em>zman tfilah</em>. This can be sunrise or any <em>alos</em> passed 608 * to this method. 609 * @param endOfDay 610 * the end of day for calculating <em>zman tfilah</em>. This can be sunset or any <em>tzais</em> passed to 611 * this method. 612 * @return the <code>Date</code> of the latest <em>zman tfilah</em> based on the start and end of day times passed to this 613 * method. If the calculation can't be computed such as in the Arctic Circle where there is at least one day 614 * a year where the sun does not rise, and one where it does not set, a <code>null</code> will be returned. See 615 * detailed explanation on top of the {@link AstronomicalCalendar} documentation. 616 * @see #getSofZmanShma(Date, Date, boolean) 617 */ 618 public Date getSofZmanTfila(Date startOfDay, Date endOfDay) { 619 return getSofZmanTfila(startOfDay, endOfDay, false); 620 } 621 622 /** 623 * This method returns the latest <em>zman tfila</em> (time to recite shema in the morning) that is 4 * 624 * {@link #getShaahZmanisGra() <em>shaos zmaniyos</em> }(solar hours) after {@link #getSunrise() sunrise} or 625 * {@link #getSeaLevelSunrise() sea level sunrise} (depending on the {@link #isUseElevation()} setting), according 626 * to the <a href="https://en.wikipedia.org/wiki/Vilna_Gaon">GRA</a>. 627 * The day is calculated from {@link #getSeaLevelSunrise() sea level sunrise} to {@link #getSeaLevelSunset() sea level 628 * sunset} or from {@link #getSunrise() sunrise} to {@link #getSunset() sunset} (depending on the 629 * {@link #isUseElevation()} setting). 630 * 631 * @see #getSofZmanTfila(Date, Date) 632 * @see #getShaahZmanisGra() 633 * @see ComplexZmanimCalendar#getSofZmanTfilaBaalHatanya() 634 * @return the <code>Date</code> of the latest <em>zman tfilah</em>. If the calculation can't be computed such as in 635 * the Arctic Circle where there is at least one day a year where the sun does not rise, and one where it 636 * does not set, a <code>null</code> will be returned. See detailed explanation on top of the 637 * {@link AstronomicalCalendar} documentation. 638 */ 639 public Date getSofZmanTfilaGRA() { 640 return getSofZmanTfila(getElevationAdjustedSunrise(), getElevationAdjustedSunset(), true); 641 } 642 643 /** 644 * This method returns the latest <em>zman tfila</em> (time to recite shema in the morning) that is 4 * 645 * {@link #getShaahZmanisMGA() <em>shaos zmaniyos</em>} (solar hours) after {@link #getAlos72()}, according to the 646 * <em><a href="https://en.wikipedia.org/wiki/Avraham_Gombiner">Magen Avraham (MGA)</a></em>. The day is calculated 647 * from 72 minutes before {@link #getSeaLevelSunrise() sea level sunrise} to 72 minutes after {@link 648 * #getSeaLevelSunset() sea level sunset} or from 72 minutes before {@link #getSunrise() sunrise} to {@link #getSunset() 649 * sunset} (depending on the {@link #isUseElevation()} setting). 650 * 651 * @return the <code>Date</code> of the latest <em>zman tfila</em>. If the calculation can't be computed such as in 652 * the Arctic Circle where there is at least one day a year where the sun does not rise, and one where it 653 * does not set, a <code>null</code> will be returned. See detailed explanation on top of the 654 * {@link AstronomicalCalendar} documentation. 655 * @see #getSofZmanTfila(Date, Date) 656 * @see #getShaahZmanisMGA() 657 * @see #getAlos72() 658 */ 659 public Date getSofZmanTfilaMGA() { 660 return getSofZmanTfila(getAlos72(), getTzais72(), true); 661 } 662 663 /** 664 * A generic method for calculating <em>mincha gedola</em> (the earliest time to recite the <em>mincha</em> prayers) that 665 * is 6.5 * <em>shaos zmaniyos</em> (temporal hours) after the start of the day, calculated using the start and end of the 666 * day passed to this method. The time from the start of day to the end of day are divided into 12 <em>shaos zmaniyos</em> 667 * (temporal hours), and <em>mincha gedola</em> is calculated as 6.5 of those <em>shaos zmaniyos</em> after the beginning 668 * of the day. As an example, passing {@link #getSunrise() sunrise} and {@link #getSunset() sunset} or {@link 669 * #getSeaLevelSunrise() sea level sunrise} and {@link #getSeaLevelSunset() sea level sunset} (depending on the {@link 670 * #isUseElevation()} elevation setting) to this method will return <em>mincha gedola</em> according to the opinion of the 671 * <a href="https://en.wikipedia.org/wiki/Vilna_Gaon">GRA</a>. Alternatively, this method uses {@link 672 * #isUseAstronomicalChatzosForOtherZmanim()} to control if the time is based on 6.5 <em>shaos zmaniyos</em> into the day 673 * mentioned above, or as half an hour <em>zmaniyos</em> based on the second half of the day after <em>chatzos</em> ({@link 674 * #getSunTransit() astronomical <em>chatzos</em>} if supported by the {@link AstronomicalCalculator calculator} and {@link 675 * #isUseAstronomicalChatzos() configured} or {@link #getChatzosAsHalfDay() <em>chatzos</em> as half a day} if not. This 676 * method's synchronous parameter indicates if the start and end of day for the calculation are synchronous, having the same 677 * offset. This is typically the case, but some <em>zmanim</em> calculations are based on a start and end at different offsets 678 * from the real start and end of the day, such as starting the day at <em>alos</em> and an ending it at <em>tzais Geonim</em> 679 * or some other variant. If the day is not synchronous a {@link #getHalfDayBasedZman(Date, Date, double) half-day based 680 * calculations} will be bypassed. It would be illogical to use a half-day based calculation that start/end at <em>chatzos</em> 681 * when the two "halves" of the day are not equal, and the halfway point between them is not at <em>chatzos</em>. 682 * 683 * @param startOfDay 684 * the start of day for calculating <em>Mincha gedola</em>. This can be sunrise or any <em>alos</em> passed 685 * to this method. 686 * @param endOfDay 687 * the end of day for calculating <em>Mincha gedola</em>. This can be sunset or any <em>tzais</em> passed 688 * to this method. 689 * @param synchronous 690 * If the <em>zman</em> has a synchronous start and end of the day. If this is <code>false</code>, using a {@link 691 * #isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by 692 * definition <em>chatzos</em> will not be the middle of the day for the <em>zman</em>. 693 * @return the <code>Date</code> of the time of <em>Mincha gedola</em> based on the start and end of day times 694 * passed to this method. If the calculation can't be computed such as in the Arctic Circle where there is 695 * at least one day a year where the sun does not rise, and one where it does not set, a <code>null</code> will 696 * be returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. 697 * @see #getSunTransit() 698 * @see #getChatzosAsHalfDay() 699 * @see #getChatzos() 700 * @see #isUseAstronomicalChatzos() 701 * @see #isUseAstronomicalChatzosForOtherZmanim() 702 */ 703 public Date getMinchaGedola(Date startOfDay, Date endOfDay, boolean synchronous) { 704 if (isUseAstronomicalChatzosForOtherZmanim() && synchronous) { 705 return getHalfDayBasedZman(getChatzos(), endOfDay, 0.5); 706 } else { 707 return getShaahZmanisBasedZman(startOfDay, endOfDay, 6.5); 708 } 709 } 710 711 /** 712 * A generic method for calculating <em>mincha gedola</em> that calls {@link #getMinchaGedola(Date, Date, boolean)} passing 713 * <code>false</code> to the synchronous parameter since there is no way to know if the start and end of the day are 714 * synchronous. Passing true when they are not synchronous is too much of a risk. See information on that method for more 715 * details. 716 * @param startOfDay 717 * the start of day for calculating <em>Mincha gedola</em>. This can be sunrise or any <em>alos</em> passed 718 * to this method. 719 * @param endOfDay 720 * the end of day for calculating <em>Mincha gedola</em>. This can be sunset or any <em>tzais</em> passed to 721 * this method. 722 * @return the <code>Date</code> of the latest <em>Mincha gedola</em> based on the start and end of day times passed to this 723 * method. If the calculation can't be computed such as in the Arctic Circle where there is at least one day 724 * a year where the sun does not rise, and one where it does not set, a <code>null</code> will be returned. See 725 * detailed explanation on top of the {@link AstronomicalCalendar} documentation. 726 * @see #getMinchaGedola(Date, Date, boolean) 727 */ 728 public Date getMinchaGedola(Date startOfDay, Date endOfDay) { 729 return getMinchaGedola(startOfDay, endOfDay, false); 730 } 731 732 /** 733 * This method returns the latest <em>mincha gedola</em>,the earliest time one can pray <em>mincha</em> that is 6.5 * 734 * {@link #getShaahZmanisGra() <em>shaos zmaniyos</em>} (solar hours) after {@link #getSunrise() sunrise} or 735 * {@link #getSeaLevelSunrise() sea level sunrise} (depending on the {@link #isUseElevation()} setting), according 736 * to the <a href="https://en.wikipedia.org/wiki/Vilna_Gaon">GRA</a>. <em>Mincha gedola</em> is the earliest 737 * time one can pray <em>mincha</em>. The Ramba"m is of the opinion that it is better to delay <em>mincha</em> until 738 * {@link #getMinchaKetana() <em>mincha ketana</em>} while the Ra"sh, Tur, GRA and others are of the 739 * opinion that <em>mincha</em> can be prayed <em>lechatchila</em> starting at <em>mincha gedola</em>. 740 * The day is calculated from {@link #getSeaLevelSunrise() sea level sunrise} to {@link #getSeaLevelSunset() sea level 741 * sunset} or {@link #getSunrise() sunrise} to {@link #getSunset() sunset} (depending on the {@link #isUseElevation()} 742 * setting). 743 * @todo Consider adjusting this to calculate the time as half an hour <em>zmaniyos</em> after either {@link 744 * #getSunTransit() astronomical <em>chatzos</em>} or {@link #getChatzosAsHalfDay() <em>chatzos</em> as half a day} 745 * for {@link AstronomicalCalculator calculators} that support it, based on {@link #isUseAstronomicalChatzos()}. 746 * 747 * @see #getMinchaGedola(Date, Date) 748 * @see #getShaahZmanisGra() 749 * @see #getMinchaKetana() 750 * @see ComplexZmanimCalendar#getMinchaGedolaBaalHatanya() 751 * @return the <code>Date</code> of the time of mincha gedola. If the calculation can't be computed such as in the 752 * Arctic Circle where there is at least one day a year where the sun does not rise, and one where it does 753 * not set, a <code>null</code> will be returned. See detailed explanation on top of the 754 * {@link AstronomicalCalendar} documentation. 755 */ 756 public Date getMinchaGedola() { 757 return getMinchaGedola(getElevationAdjustedSunrise(), getElevationAdjustedSunset(), true); 758 } 759 760 /** 761 * A generic method for calculating <em>samuch lemincha ketana</em>, / near <em>mincha ketana</em> time that is half 762 * an hour before {@link #getMinchaKetana(Date, Date)} or 9 * <em>shaos zmaniyos</em> (temporal hours) after the 763 * start of the day, calculated using the start and end of the day passed to this method. 764 * The time from the start of day to the end of day are divided into 12 <em>shaos zmaniyos</em> (temporal hours), and 765 * <em>samuch lemincha ketana</em> is calculated as 9 of those <em>shaos zmaniyos</em> after the beginning of the day. 766 * For example, passing {@link #getSunrise() sunrise} and {@link #getSunset() sunset} or {@link #getSeaLevelSunrise() sea 767 * level sunrise} and {@link #getSeaLevelSunset() sea level sunset} (depending on the {@link #isUseElevation()} elevation 768 * setting) to this method will return <em>samuch lemincha ketana</em> according to the opinion of the 769 * <a href="https://en.wikipedia.org/wiki/Vilna_Gaon">GRA</a>. See the <a href= 770 * "https://hebrewbooks.org/pdfpager.aspx?req=60387&st=&pgnum=294">Mechaber and Mishna Berurah 232</a> and <a href= 771 * "https://hebrewbooks.org/pdfpager.aspx?req=60388&pgnum=34">249:2</a>. 772 * 773 * @param startOfDay 774 * the start of day for calculating <em>samuch lemincha ketana</em>. This can be sunrise or any <em>alos</em> 775 * passed to this method. 776 * @param endOfDay 777 * the end of day for calculating <em>samuch lemincha ketana</em>. This can be sunset or any <em>tzais</em> 778 * passed to this method. 779 * @param synchronous 780 * If the <em>zman</em> has a synchronous start and end of the day. If this is <code>false</code>, using a {@link 781 * #isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by 782 * definition <em>chatzos</em> will not be the middle of the day for the <em>zman</em>. 783 * @return the <code>Date</code> of the time of <em>Mincha ketana</em> based on the start and end of day times 784 * passed to this method. If the calculation can't be computed such as in the Arctic Circle where there is 785 * at least one day a year where the sun does not rise, and one where it does not set, a <code>null</code> will 786 * be returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. 787 * 788 * @see ComplexZmanimCalendar#getSamuchLeMinchaKetanaGRA() 789 * @see ComplexZmanimCalendar#getSamuchLeMinchaKetana16Point1Degrees() 790 * @see ComplexZmanimCalendar#getSamuchLeMinchaKetana72Minutes() 791 */ 792 public Date getSamuchLeMinchaKetana(Date startOfDay, Date endOfDay, boolean synchronous) { 793 if (isUseAstronomicalChatzosForOtherZmanim() && synchronous) { 794 return getHalfDayBasedZman(getChatzos(), endOfDay, 3); 795 } else { 796 return getShaahZmanisBasedZman(startOfDay, endOfDay, 9); 797 } 798 } 799 800 /** 801 * A generic method for calculating <em>samuch lemincha ketana</em> that calls {@link #getSamuchLeMinchaKetana(Date, Date, boolean)} 802 * passing <code>false</code> to the synchronous parameter since there is no way to know if the start and end of the day are 803 * synchronous. Passing true when they are not synchronous is too much of a risk. See information on that method for more details. 804 * @param startOfDay 805 * the start of day for calculating <em>samuch lemincha ketana</em>. This can be sunrise or any <em>alos</em> 806 * passed to this method. 807 * @param endOfDay 808 * the end of day for calculating <em>samuch lemincha ketana</em>. This can be sunset or any <em>tzais</em> 809 * passed to this method. 810 * @return the <code>Date</code> of the time of <em>samuch lemincha ketana</em> based on the start and end of day times 811 * passed to this method. If the calculation can't be computed such as in the Arctic Circle where there is 812 * at least one day a year where the sun does not rise, and one where it does not set, a <code>null</code> will 813 * be returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. 814 * @see #getSamuchLeMinchaKetana(Date, Date, boolean) 815 */ 816 public Date getSamuchLeMinchaKetana(Date startOfDay, Date endOfDay) { 817 return getSamuchLeMinchaKetana(startOfDay, endOfDay, false); 818 } 819 820 /** 821 * A generic method for calculating <em>mincha ketana</em>, (the preferred time to recite the mincha prayers in 822 * the opinion of the <em><a href="https://en.wikipedia.org/wiki/Maimonides">Rambam</a></em> and others) that is 823 * 9.5 * <em>shaos zmaniyos</em> (temporal hours) after the start of the day, calculated using the start and end 824 * of the day passed to this method. 825 * The time from the start of day to the end of day are divided into 12 <em>shaos zmaniyos</em> (temporal hours), and 826 * <em>mincha ketana</em> is calculated as 9.5 of those <em>shaos zmaniyos</em> after the beginning of the day. As an 827 * example, passing {@link #getSunrise() sunrise} and {@link #getSunset() sunset} or {@link #getSeaLevelSunrise() sea 828 * level sunrise} and {@link #getSeaLevelSunset() sea level sunset} (depending on the {@link #isUseElevation()} 829 * elevation setting) to this method will return <em>mincha ketana</em> according to the opinion of the 830 * <a href="https://en.wikipedia.org/wiki/Vilna_Gaon">GRA</a>. This method's synchronous parameter indicates if the start 831 * and end of day for the calculation are synchronous, having the same offset. This is typically the case, but some 832 * <em>zmanim</em> calculations are based on a start and end at different offsets from the real start and end of the day, 833 * 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 834 * is not synchronous a {@link #getHalfDayBasedZman(Date, Date, double) half-day based calculations} will be bypassed. 835 * It would be illogical to use a half-day based calculation that start/end at <em>chatzos</em> when the two "halves" of 836 * the day are not equal, and the halfway point between them is not at <em>chatzos</em>. 837 * 838 * @param startOfDay 839 * the start of day for calculating <em>Mincha ketana</em>. This can be sunrise or any <em>alos</em> passed 840 * to this method. 841 * @param endOfDay 842 * the end of day for calculating <em>Mincha ketana</em>. This can be sunset or any <em>tzais</em> passed to 843 * this method. 844 * @param synchronous 845 * If the <em>zman</em> has a synchronous start and end of the day. If this is <code>false</code>, using a {@link 846 * #isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by 847 * definition <em>chatzos</em> will not be the middle of the day for the <em>zman</em>. 848 * @return the <code>Date</code> of the time of <em>Mincha ketana</em> based on the start and end of day times 849 * passed to this method. If the calculation can't be computed such as in the Arctic Circle where there is 850 * at least one day a year where the sun does not rise, and one where it does not set, a <code>null</code> will 851 * be returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. 852 */ 853 public Date getMinchaKetana(Date startOfDay, Date endOfDay, boolean synchronous) { 854 if (isUseAstronomicalChatzosForOtherZmanim() && synchronous) { 855 return getHalfDayBasedZman(getChatzos(), endOfDay, 3.5); 856 } else { 857 return getShaahZmanisBasedZman(startOfDay, endOfDay, 9.5); 858 } 859 } 860 861 /** 862 * A generic method for calculating <em>mincha ketana</em> that calls {@link #getMinchaKetana(Date, Date, boolean)} passing 863 * <code>false</code> to the synchronous parameter since there is no way to know if the start and end of the day are synchronous. 864 * Passing true when they are not synchronous is too much of a risk. See information on that method for more details. 865 * @param startOfDay 866 * the start of day for calculating <em>Mincha ketana</em>. This can be sunrise or any <em>alos</em> passed 867 * to this method. 868 * @param endOfDay 869 * the end of day for calculating <em>Mincha ketana</em>. This can be sunset or any <em>tzais</em> passed to 870 * this method. 871 * @return the <code>Date</code> of the time of <em>Mincha ketana</em> based on the start and end of day times 872 * passed to this method. If the calculation can't be computed such as in the Arctic Circle where there is 873 * at least one day a year where the sun does not rise, and one where it does not set, a <code>null</code> will 874 * be returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. 875 * @see #getMinchaKetana(Date, Date, boolean) 876 */ 877 public Date getMinchaKetana(Date startOfDay, Date endOfDay) { 878 return getMinchaKetana(startOfDay, endOfDay, false); 879 } 880 881 /** 882 * This method returns <em>mincha ketana</em>,the preferred earliest time to pray <em>mincha</em> in the 883 * opinion of the <em><a href="https://en.wikipedia.org/wiki/Maimonides">Rambam</a></em> and others, that is 9.5 884 * * {@link #getShaahZmanisGra() <em>shaos zmaniyos</em>} (solar hours) after {@link #getSunrise() sunrise} or 885 * {@link #getSeaLevelSunrise() sea level sunrise} (depending on the {@link #isUseElevation()} setting), according 886 * to the <a href="https://en.wikipedia.org/wiki/Vilna_Gaon">GRA</a>. For more information on this see the 887 * documentation on {@link #getMinchaGedola() <em>mincha gedola</em>}. 888 * The day is calculated from {@link #getSeaLevelSunrise() sea level sunrise} to {@link #getSeaLevelSunset() sea level 889 * sunset} or from {@link #getSunrise() sunrise} to {@link #getSunset() sunset} (depending on the {@link #isUseElevation()} 890 * setting. 891 * 892 * @see #getMinchaKetana(Date, Date) 893 * @see #getShaahZmanisGra() 894 * @see #getMinchaGedola() 895 * @see ComplexZmanimCalendar#getMinchaKetanaBaalHatanya() 896 * @return the <code>Date</code> of the time of mincha ketana. If the calculation can't be computed such as in the 897 * Arctic Circle where there is at least one day a year where the sun does not rise, and one where it does 898 * not set, a <code>null</code> will be returned. See detailed explanation on top of the 899 * {@link AstronomicalCalendar} documentation. 900 */ 901 public Date getMinchaKetana() { 902 return getMinchaKetana(getElevationAdjustedSunrise(), getElevationAdjustedSunset(), true); 903 } 904 905 /** 906 * A generic method for calculating <em>plag hamincha</em> (the earliest time that Shabbos can be started) that is 907 * 10.75 hours after the start of the day, (or 1.25 hours before the end of the day) based on the start and end of 908 * the day passed to the method. 909 * The time from the start of day to the end of day are divided into 12 <em>shaos zmaniyos</em> (temporal hours), and 910 * <em>plag hamincha</em> is calculated as 10.75 of those <em>shaos zmaniyos</em> after the beginning of the day. As an 911 * example, passing {@link #getSunrise() sunrise} and {@link #getSunset() sunset} or {@link #getSeaLevelSunrise() sea level 912 * sunrise} and {@link #getSeaLevelSunset() sea level sunset} (depending on the {@link #isUseElevation()} elevation 913 * setting) to this method will return <em>plag mincha</em> according to the opinion of the 914 * <a href="https://en.wikipedia.org/wiki/Vilna_Gaon">GRA</a>. This method's synchronous parameter indicates if the start 915 * and end of day for the calculation are synchronous, having the same offset. This is typically the case, but some 916 * <em>zmanim</em> calculations are based on a start and end at different offsets from the real start and end of the day, 917 * 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 918 * is not synchronous a {@link #getHalfDayBasedZman(Date, Date, double) half-day based calculations} will be bypassed. It 919 * would be illogical to use a half-day based calculation that start/end at <em>chatzos</em> when the two "halves" of the 920 * day are not equal, and the halfway point between them is not at <em>chatzos</em>. 921 * 922 * @param startOfDay 923 * the start of day for calculating <em>plag hamincha</em>. This can be sunrise or any <em>alos</em> passed to 924 * this method. 925 * @param endOfDay 926 * the end of day for calculating <em>plag hamincha</em>. This can be sunset or any <em>tzais</em> passed to 927 * this method. 928 * @param synchronous 929 * If the <em>zman</em> has a synchronous start and end of the day. If this is <code>false</code>, using a {@link 930 * #isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by 931 * definition <em>chatzos</em> will not be the middle of the day for the <em>zman</em>. 932 * @return the <code>Date</code> of the time of <em>plag hamincha</em> based on the start and end of day times 933 * passed to this method. If the calculation can't be computed such as in the Arctic Circle where there is 934 * at least one day a year where the sun does not rise, and one where it does not set, a <code>null</code> 935 * will be returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. 936 */ 937 public Date getPlagHamincha(Date startOfDay, Date endOfDay, boolean synchronous) { 938 if (isUseAstronomicalChatzosForOtherZmanim() && synchronous) { 939 return getHalfDayBasedZman(getChatzos(), endOfDay, 4.75); 940 } else { 941 return getShaahZmanisBasedZman(startOfDay, endOfDay, 10.75); 942 } 943 } 944 945 /** 946 * A generic method for calculating <em>plag hamincha</em> that calls {@link #getPlagHamincha(Date, Date, boolean)} passing 947 * <code>false</code> to the synchronous parameter since there is no way to know if the start and end of the day are synchronous. 948 * Passing true when they are not synchronous is too much of a risk. See information on that method for more details. 949 * @param startOfDay 950 * the start of day for calculating <em>plag hamincha</em>. This can be sunrise or any <em>alos</em> passed to this method. 951 * @param endOfDay 952 * the end of day for calculating <em>plag hamincha</em>. This can be sunset or any <em>tzais</em> passed to this method. 953 * @return the <code>Date</code> of the time of <em>plag hamincha</em> based on the start and end of day times 954 * passed to this method. If the calculation can't be computed such as in the Arctic Circle where there is 955 * at least one day a year where the sun does not rise, and one where it does not set, a <code>null</code> 956 * will be returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. 957 * @see #getPlagHamincha(Date, Date, boolean) 958 */ 959 public Date getPlagHamincha(Date startOfDay, Date endOfDay) { 960 return getPlagHamincha(startOfDay, endOfDay, false); 961 } 962 963 /** 964 * This method returns <em>plag hamincha</em>, that is 10.75 * {@link #getShaahZmanisGra() <em>shaos zmaniyos</em>} 965 * (solar hours) after {@link #getSunrise() sunrise} or {@link #getSeaLevelSunrise() sea level sunrise} (depending on 966 * the {@link #isUseElevation()} setting), according to the <a href="https://en.wikipedia.org/wiki/Vilna_Gaon" 967 * >GRA</a>. <em>Plag hamincha</em> is the earliest time that <em>Shabbos</em> can be started. 968 * The day is calculated from {@link #getSeaLevelSunrise() sea level sunrise} to {@link #getSeaLevelSunset() sea level 969 * sunset} or {@link #getSunrise() sunrise} to {@link #getSunset() sunset} (depending on the {@link #isUseElevation()} 970 * 971 * @see #getPlagHamincha(Date, Date, boolean) 972 * @see #getPlagHamincha(Date, Date) 973 * @see ComplexZmanimCalendar#getPlagHaminchaBaalHatanya() 974 * @return the <code>Date</code> of the time of <em>plag hamincha</em>. If the calculation can't be computed such as 975 * in the Arctic Circle where there is at least one day a year where the sun does not rise, and one where it 976 * does not set, a <code>null</code> will be returned. See detailed explanation on top of the 977 * {@link AstronomicalCalendar} documentation. 978 */ 979 public Date getPlagHamincha() { 980 return getPlagHamincha(getElevationAdjustedSunrise(), getElevationAdjustedSunset(), true); 981 } 982 983 /** 984 * A method that returns a <em>shaah zmanis</em> ({@link #getTemporalHour(Date, Date) temporal hour}) according to 985 * the opinion of the <a href="https://en.wikipedia.org/wiki/Vilna_Gaon">GRA</a>. This calculation divides the day 986 * based on the opinion of the <em>GRA</em> that the day runs from from {@link #getSeaLevelSunrise() sea level 987 * sunrise} to {@link #getSeaLevelSunset() sea level sunset} or {@link #getSunrise() sunrise} to {@link #getSunset() 988 * sunset} (depending on the {@link #isUseElevation()} setting). The day is split into 12 equal parts with each one 989 * being a <em>shaah zmanis</em>. This method is similar to {@link #getTemporalHour()}, but can account for elevation. 990 * 991 * @return the <code>long</code> millisecond length of a <em>shaah zmanis</em> calculated from sunrise to sunset. 992 * If the calculation can't be computed such as in the Arctic Circle where there is at least one day a year 993 * where the sun does not rise, and one where it does not set, {@link Long#MIN_VALUE} will be returned. See 994 * detailed explanation on top of the {@link AstronomicalCalendar} documentation. 995 * @see #getTemporalHour(Date, Date) 996 * @see #getSeaLevelSunrise() 997 * @see #getSeaLevelSunset() 998 * @see ComplexZmanimCalendar#getShaahZmanisBaalHatanya() 999 */ 1000 public long getShaahZmanisGra() { 1001 return getTemporalHour(getElevationAdjustedSunrise(), getElevationAdjustedSunset()); 1002 } 1003 1004 /** 1005 * A method that returns a <em>shaah zmanis</em> (temporal hour) according to the opinion of the <em><a href= 1006 * "https://en.wikipedia.org/wiki/Avraham_Gombiner">Magen Avraham (MGA)</a></em> based on a 72-minute <em>alos</em> 1007 * and <em>tzais</em>. This calculation divides the day that runs from dawn to dusk (for <em>sof zman krias shema</em> and 1008 * <em>tfila</em>). Dawn for this calculation is 72 minutes before {@link #getSunrise() sunrise} or {@link #getSeaLevelSunrise() 1009 * sea level sunrise} (depending on the {@link #isUseElevation()} elevation setting) and dusk is 72 minutes after {@link 1010 * #getSunset() sunset} or {@link #getSeaLevelSunset() sea level sunset} (depending on the {@link #isUseElevation()} elevation 1011 * setting). This day is split into 12 equal parts with each part being a <em>shaah zmanis</em>. Alternate methods of calculating 1012 * a <em>shaah zmanis</em> according to the Magen Avraham (MGA) are available in the subclass {@link ComplexZmanimCalendar}. 1013 * 1014 * @return the <code>long</code> millisecond length of a <em>shaah zmanis</em>. If the calculation can't be computed 1015 * such as in the Arctic Circle where there is at least one day a year where the sun does not rise, and one 1016 * where it does not set, {@link Long#MIN_VALUE} will be returned. See detailed explanation on top of the 1017 * {@link AstronomicalCalendar} documentation. 1018 */ 1019 public long getShaahZmanisMGA() { 1020 return getTemporalHour(getAlos72(), getTzais72()); 1021 } 1022 1023 /** 1024 * Default constructor will set a default {@link GeoLocation#GeoLocation()}, a default 1025 * {@link AstronomicalCalculator#getDefault() AstronomicalCalculator} and default the calendar to the current date. 1026 * 1027 * @see AstronomicalCalendar#AstronomicalCalendar() 1028 */ 1029 public ZmanimCalendar() { 1030 super(); 1031 } 1032 1033 /** 1034 * A constructor that takes a {@link GeoLocation} as a parameter. 1035 * 1036 * @param location 1037 * the location 1038 */ 1039 public ZmanimCalendar(GeoLocation location) { 1040 super(location); 1041 } 1042 1043 /** 1044 * A method to get the offset in minutes before {@link AstronomicalCalendar#getSeaLevelSunset() sea level sunset} which 1045 * is used in calculating candle lighting time. The default time used is 18 minutes before sea level sunset. Some 1046 * calendars use 15 minutes, while the custom in Jerusalem is to use a 40-minute offset. Please check the local custom 1047 * for candle lighting time. 1048 * 1049 * @return Returns the currently set candle lighting offset in minutes. 1050 * @see #getCandleLighting() 1051 * @see #setCandleLightingOffset(double) 1052 */ 1053 public double getCandleLightingOffset() { 1054 return candleLightingOffset; 1055 } 1056 1057 /** 1058 * A method to set the offset in minutes before {@link AstronomicalCalendar#getSeaLevelSunset() sea level sunset} that is 1059 * used in calculating candle lighting time. The default time used is 18 minutes before sunset. Some calendars use 15 1060 * minutes, while the custom in Jerusalem is to use a 40-minute offset. 1061 * 1062 * @param candleLightingOffset 1063 * The candle lighting offset to set in minutes. 1064 * @see #getCandleLighting() 1065 * @see #getCandleLightingOffset() 1066 */ 1067 public void setCandleLightingOffset(double candleLightingOffset) { 1068 this.candleLightingOffset = candleLightingOffset; 1069 } 1070 1071 /** 1072 * This is a utility method to determine if the current Date (date-time) passed in has a <em>melacha</em> (work) prohibition. 1073 * Since there are many opinions on the time of <em>tzais</em>, the <em>tzais</em> for the current day has to be passed to this 1074 * class. Sunset is the classes current day's {@link #getElevationAdjustedSunset() elevation adjusted sunset} that observes the 1075 * {@link #isUseElevation()} settings. The {@link JewishCalendar#getInIsrael()} will be set by the inIsrael parameter. 1076 * 1077 * @param currentTime the current time 1078 * @param tzais the time of tzais 1079 * @param inIsrael whether to use Israel holiday scheme or not 1080 * 1081 * @return true if <em>melacha</em> is prohibited or false if it is not. 1082 * 1083 * @see JewishCalendar#isAssurBemelacha() 1084 * @see JewishCalendar#hasCandleLighting() 1085 * @see JewishCalendar#setInIsrael(boolean) 1086 */ 1087 public boolean isAssurBemlacha(Date currentTime, Date tzais, boolean inIsrael) { 1088 JewishCalendar jewishCalendar = new JewishCalendar(); 1089 jewishCalendar.setGregorianDate(getCalendar().get(Calendar.YEAR), getCalendar().get(Calendar.MONTH), 1090 getCalendar().get(Calendar.DAY_OF_MONTH)); 1091 jewishCalendar.setInIsrael(inIsrael); 1092 1093 if (jewishCalendar.hasCandleLighting() && currentTime.compareTo(getElevationAdjustedSunset()) >= 0) { //erev shabbos, YT or YT sheni and after shkiah 1094 return true; 1095 } 1096 1097 //is shabbos or YT and it is before tzais 1098 return jewishCalendar.isAssurBemelacha() && currentTime.compareTo(tzais) <= 0; 1099 } 1100 1101 /** 1102 * A generic utility method for calculating any <em>shaah zmanis</em> (temporal hour) based <em>zman</em> with the 1103 * day defined as the start and end of day (or night) and the number of <em>shaos zmaniyos</em> passed to the 1104 * method. This simplifies the code in other methods such as {@link #getPlagHamincha(Date, Date)} and cuts down on 1105 * code replication. As an example, passing {@link #getSunrise() sunrise} and {@link #getSunset() sunset} or {@link 1106 * #getSeaLevelSunrise() sea level sunrise} and {@link #getSeaLevelSunset() sea level sunset} (depending on the 1107 * {@link #isUseElevation()} elevation setting) and 10.75 hours to this method will return <em>plag mincha</em> 1108 * according to the opinion of the <a href="https://en.wikipedia.org/wiki/Vilna_Gaon">GRA</a>. 1109 * 1110 * @param startOfDay 1111 * the start of day for calculating the <em>zman</em>. This can be sunrise or any <em>alos</em> passed 1112 * to this method. 1113 * @param endOfDay 1114 * the end of day for calculating the <em>zman</em>. This can be sunset or any <em>tzais</em> passed to 1115 * this method. 1116 * @param hours 1117 * the number of <em>shaos zmaniyos</em> (temporal hours) to offset from the start of day 1118 * @return the <code>Date</code> of the time of <em>zman</em> with the <em>shaos zmaniyos</em> (temporal hours) 1119 * in the day offset from the start of day passed to this method. If the calculation can't be computed such 1120 * as in the Arctic Circle where there is at least one day a year where the sun does not rise, and one 1121 * where it does not set, a <code>null</code> will be returned. See detailed explanation on top of the 1122 * {@link AstronomicalCalendar} documentation. 1123 */ 1124 public Date getShaahZmanisBasedZman(Date startOfDay, Date endOfDay, double hours) { 1125 long shaahZmanis = getTemporalHour(startOfDay, endOfDay); 1126 return getTimeOffset(startOfDay, shaahZmanis * hours); 1127 } 1128 1129 /** 1130 * A utility method that returns the percentage of a <em>shaah zmanis</em> after sunset (or before sunrise) for a given degree 1131 * offset. For the <a href="https://kosherjava.com/2022/01/12/equinox-vs-equilux-zmanim-calculations/">equilux</a> where there 1132 * is a 720-minute day, passing 16.1° for the location of Jerusalem will return about 1.2. This will work for any location 1133 * or date, but will typically only be of interest at the equinox/equilux to calculate the percentage of a <em>shaah zmanis</em> 1134 * for those who want to use the <a href="https://en.wikipedia.org/wiki/Abraham_Cohen_Pimentel">Minchas Cohen</a> in Ma'amar 2:4 1135 * and the <a href="https://en.wikipedia.org/wiki/Hezekiah_da_Silva">Pri Chadash</a> who calculate <em>tzais</em> as a percentage 1136 * of the day after sunset. While the Minchas Cohen only applies this to 72 minutes or a 1/10 of the day around the world (based 1137 * on the equinox / equilux in Israel), this method allows calculations for any degree level for any location. 1138 * 1139 * @param degrees 1140 * the number of degrees below the horizon after sunset. 1141 * @param sunset 1142 * if <code>true</code> the calculation should be degrees after sunset, or if <code>false</code>, degrees before sunrise. 1143 * @return the <code>double</code> percentage of a <em>sha'ah zmanis</em> for a given set of degrees below the astronomical horizon 1144 * for the current calendar. If the calculation can't be computed a {@link Double#MIN_VALUE} will be returned. See detailed 1145 * explanation on top of the page. 1146 */ 1147 public double getPercentOfShaahZmanisFromDegrees(double degrees, boolean sunset) { 1148 Date seaLevelSunrise = getSeaLevelSunrise(); 1149 Date seaLevelSunset = getSeaLevelSunset(); 1150 Date twilight = null; 1151 if (sunset) { 1152 twilight = getSunsetOffsetByDegrees(GEOMETRIC_ZENITH + degrees); 1153 } else { 1154 twilight = getSunriseOffsetByDegrees(GEOMETRIC_ZENITH + degrees); 1155 } 1156 if (seaLevelSunrise == null || seaLevelSunset == null || twilight == null) { 1157 return Double.MIN_VALUE; 1158 } 1159 double shaahZmanis = (seaLevelSunset.getTime() - seaLevelSunrise.getTime()) / 12.0; 1160 long riseSetToTwilight; 1161 if (sunset) { 1162 riseSetToTwilight = twilight.getTime() - seaLevelSunset.getTime(); 1163 } else { 1164 riseSetToTwilight = seaLevelSunrise.getTime() - twilight.getTime(); 1165 } 1166 return riseSetToTwilight / shaahZmanis; 1167 } 1168 1169 /** 1170 * A utility method to calculate <em>zmanim</em> based on <a href="https://en.wikipedia.org/wiki/Moshe_Feinstein">Rav Moshe 1171 * Feinstein</a> and others as calculated in <a href="https://en.wikipedia.org/wiki/Mesivtha_Tifereth_Jerusalem">MTJ</a>, <a href= 1172 * "https://en.wikipedia.org/wiki/Mesivtha_Tifereth_Jerusalem">Yeshiva of Staten Island</a>, and Camp Yeshiva 1173 * of Staten Island and other calendars. The day is split in two, from <em>alos</em> / sunrise to <em>chatzos</em>, and the 1174 * second half of the day, from <em>chatzos</em> to sunset / <em>tzais</em>. Morning based times are calculated. based on the first 1175 * 6 hours of the day, and afternoon times based on the second half of the day. As an example, passing 0.5, a start of 1176 * <em>chatzos</em> and an end of day as sunset will return the time of <em>mincha gedola</em> GRA as half an hour <em>zmanis</em> 1177 * based on the second half of the day. Some <em>zmanim</em> calculations can be based on subtracting <em>shaos zmaniyos</em> 1178 * from the end of the day, and that is supported by passing a negative hour to this method. 1179 * 1180 * @param startOfHalfDay 1181 * The start of the half day. This would be <em>alos</em> or sunrise for morning based times such as <em>sof zman krias 1182 * shema</em> and <em>chatzos</em> for afternoon based times such as <em>mincha gedola</em>. 1183 * @param endOfHalfDay 1184 * The end of the half day. This would be <em>chatzos</em> for morning based times such as <em>sof zman krias shema</em> 1185 * and sunset or <em>tzais</em> for afternoon based times such as <em>mincha gedola</em>. 1186 * @param hours 1187 * The number of <em>shaos zmaniyos</em> (hours) to offset the beginning of the first or second half of the day. For example, 1188 * 3 for <em>sof zman Shma</em>, 0.5 for <em>mincha gedola</em> (half an hour after <em>chatzos</em>) and 4.75 for <em>plag 1189 * hamincha</em>. If the number of hours is negative, it will subtract the number of <em>shaos zmaniyos</em> from the end 1190 * of the day. 1191 * 1192 * @return the <code>Date</code> of <em>zman</em> based on calculation of the first or second half of the day. If the 1193 * calculation can't be computed such as in the Arctic Circle where there is at least one day a year where the 1194 * sun does not rise, and one where it does not set, a <code>null</code> will be returned. See detailed explanation 1195 * on top of the {@link AstronomicalCalendar} documentation. 1196 * 1197 * @see ComplexZmanimCalendar#getFixedLocalChatzos() 1198 */ 1199 public Date getHalfDayBasedZman(Date startOfHalfDay, Date endOfHalfDay, double hours) { 1200 if (startOfHalfDay == null || endOfHalfDay == null) { 1201 return null; 1202 } 1203 long shaahZmanis = getHalfDayBasedShaahZmanis(startOfHalfDay, endOfHalfDay); 1204 if (shaahZmanis == Long.MIN_VALUE) { //defensive, should not be needed 1205 return null; 1206 } 1207 if (hours >= 0) { // forward from start a day 1208 return getTimeOffset(startOfHalfDay, shaahZmanis * hours); 1209 } else { // subtract from end of day 1210 return getTimeOffset(endOfHalfDay, shaahZmanis * hours); 1211 } 1212 } 1213 1214 /** 1215 * A utility method to calculate the length of a <em>sha'ah zmanis</em> based on 1/6 of a 6-hour day. 1216 * @param startOfHalfDay The start of the half-day. This would be <em>alos</em> or sunrise for the first half of the day, 1217 * or <em>chatzos</em> for the second half of the day. 1218 * @param endOfHalfDay The end of the half-day. This would be <em>chatzos</em> for the first half of the day, or sunset or 1219 * <em>tzais</em> for the second half of the day. 1220 * @return The <code>long</code> millisecond length of a <em>shaah zmanis</em> based on 1/6 of a half-day. If the calculation 1221 * can't be computed such as in the Arctic Circle where there is at least one day a year where the sun does not rise, 1222 * and one where it does not set, {@link Long#MIN_VALUE} will be returned. See detailed explanation on top of the 1223 * {@link AstronomicalCalendar} documentation. 1224 * @see #getHalfDayBasedZman(Date, Date, double) 1225 * @see #isUseAstronomicalChatzosForOtherZmanim() 1226 * @todo Consider adjusting various shaah zmanis times to use this. 1227 */ 1228 public long getHalfDayBasedShaahZmanis(Date startOfHalfDay, Date endOfHalfDay) { 1229 if (startOfHalfDay == null || endOfHalfDay == null) { 1230 return Long.MIN_VALUE; 1231 } 1232 return (endOfHalfDay.getTime() - startOfHalfDay.getTime()) / 6; 1233 } 1234}