001/* 002 * Zmanim Java API 003 * Copyright (C) 2004-2024 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 - 2024 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 is 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>shaaos zmaniyos</em> after sunrise, but the <em>shaaos 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>shaaos zmaniyos</em> after sunrise. {@link #getPlagHamincha() <em>Plag 141 * hamincha</em>} would be calculated as 4.75 <em>shaaos zmaniyos</em> after astronomical <em>chatzos</em> as opposed to 10.75 142 * <em>shaaos 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 fall season 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>shaaos zmaniyos</em> after sunrise, but the <em>shaaos 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>shaaos zmaniyos</em> after sunrise. {@link #getPlagHamincha() <em>Plag 194 * hamincha</em>} would be calculated as 4.75 <em>shaaos zmaniyos</em> after astronomical <em>chatzos</em> as opposed to 10.75 195 * <em>shaaos 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 <em>mil</em> at 18 minutes 221 * a mil (<em><a href="https://en.wikipedia.org/wiki/Maimonides">Rambam</a></em> and others). The sun's position at 222 * 72 minutes before {@link #getSunrise sunrise} in Jerusalem <a href= 223 * "https://kosherjava.com/2022/01/12/equinox-vs-equilux-zmanim-calculations/">around the equinox / equilux</a> is 224 * 16.1° below {@link #GEOMETRIC_ZENITH geometric zenith}. 225 * 226 * @see #getAlosHashachar() 227 * @see ComplexZmanimCalendar#getAlos16Point1Degrees() 228 * @see ComplexZmanimCalendar#getTzais16Point1Degrees() 229 * @see ComplexZmanimCalendar#getSofZmanShmaMGA16Point1Degrees() 230 * @see ComplexZmanimCalendar#getSofZmanTfilaMGA16Point1Degrees() 231 * @see ComplexZmanimCalendar#getMinchaGedola16Point1Degrees() 232 * @see ComplexZmanimCalendar#getMinchaKetana16Point1Degrees() 233 * @see ComplexZmanimCalendar#getPlagHamincha16Point1Degrees() 234 * @see ComplexZmanimCalendar#getPlagAlos16Point1ToTzaisGeonim7Point083Degrees() 235 * @see ComplexZmanimCalendar#getSofZmanShmaAlos16Point1ToSunset() 236 */ 237 protected static final double ZENITH_16_POINT_1 = GEOMETRIC_ZENITH + 16.1; 238 239 /** 240 * The zenith of 8.5° below geometric zenith (90°). This calculation is used for calculating <em>alos</em> 241 * (dawn) and <em>tzais</em> (nightfall) in some opinions. This calculation is based on the position of the sun 36 242 * minutes after {@link #getSunset sunset} in Jerusalem <a href= 243 * "https://kosherjava.com/2022/01/12/equinox-vs-equilux-zmanim-calculations/">around the equinox / equilux</a>, which 244 * is 8.5° below {@link #GEOMETRIC_ZENITH geometric zenith}. The <em><a href= 245 * "https://www.worldcat.org/oclc/29283612">Ohr Meir</a></em> considers this the time that 3 small stars are visible, 246 * which is later than the required 3 medium stars. 247 * 248 * @see #getTzais() 249 * @see ComplexZmanimCalendar#getTzaisGeonim8Point5Degrees() 250 */ 251 protected static final double ZENITH_8_POINT_5 = GEOMETRIC_ZENITH + 8.5; 252 253 /** 254 * The default <em>Shabbos</em> candle lighting offset is 18 minutes. This can be changed via the 255 * {@link #setCandleLightingOffset(double)} and retrieved by the {@link #getCandleLightingOffset()}. 256 */ 257 private double candleLightingOffset = 18; 258 259 /** 260 * This method will return {@link #getSeaLevelSunrise() sea level sunrise} if {@link #isUseElevation()} is false (the 261 * default), or elevation adjusted {@link AstronomicalCalendar#getSunrise()} if it is true. This allows relevant <em>zmanim</em> 262 * in this and extending classes (such as the {@link ComplexZmanimCalendar}) to automatically adjust to the elevation setting. 263 * 264 * @return {@link #getSeaLevelSunrise()} if {@link #isUseElevation()} is false (the default), or elevation adjusted 265 * {@link AstronomicalCalendar#getSunrise()} if it is true. 266 * @see com.kosherjava.zmanim.AstronomicalCalendar#getSunrise() 267 */ 268 protected Date getElevationAdjustedSunrise() { 269 if(isUseElevation()) { 270 return super.getSunrise(); 271 } 272 return getSeaLevelSunrise(); 273 } 274 275 /** 276 * This method will return {@link #getSeaLevelSunrise() sea level sunrise} if {@link #isUseElevation()} is false (the default), 277 * or elevation adjusted {@link AstronomicalCalendar#getSunrise()} if it is true. This allows relevant <em>zmanim</em> 278 * in this and extending classes (such as the {@link ComplexZmanimCalendar}) to automatically adjust to the elevation setting. 279 * 280 * @return {@link #getSeaLevelSunset()} if {@link #isUseElevation()} is false (the default), or elevation adjusted 281 * {@link AstronomicalCalendar#getSunset()} if it is true. 282 * @see com.kosherjava.zmanim.AstronomicalCalendar#getSunset() 283 */ 284 protected Date getElevationAdjustedSunset() { 285 if(isUseElevation()) { 286 return super.getSunset(); 287 } 288 return getSeaLevelSunset(); 289 } 290 291 /** 292 * A method that returns <em>tzais</em> (nightfall) when the sun is {@link #ZENITH_8_POINT_5 8.5°} below the 293 * {@link #GEOMETRIC_ZENITH geometric horizon} (90°) after {@link #getSunset sunset}, a time that Rabbi Meir 294 * Posen in his the <em><a href="https://www.worldcat.org/oclc/29283612">Ohr Meir</a></em> calculated that 3 small 295 * stars are visible, which is later than the required 3 medium stars. See the {@link #ZENITH_8_POINT_5} constant. 296 * 297 * @see #ZENITH_8_POINT_5 298 * 299 * @return The <code>Date</code> of nightfall. If the calculation can't be computed such as northern and southern 300 * locations even south of the Arctic Circle and north of the Antarctic Circle where the sun may not reach 301 * low enough below the horizon for this calculation, a <code>null</code> will be returned. See detailed 302 * explanation on top of the {@link AstronomicalCalendar} documentation. 303 * @see #ZENITH_8_POINT_5 304 * ComplexZmanimCalendar#getTzaisGeonim8Point5Degrees() that returns an identical time to this generic <em>tzais</em> 305 */ 306 public Date getTzais() { 307 return getSunsetOffsetByDegrees(ZENITH_8_POINT_5); 308 } 309 310 /** 311 * Returns <em>alos</em> (dawn) based on the time when the sun is {@link #ZENITH_16_POINT_1 16.1°} below the 312 * eastern {@link #GEOMETRIC_ZENITH geometric horizon} before {@link #getSunrise sunrise}. This is based on the 313 * calculation that the time between dawn and sunrise (and sunset to nightfall) is 72 minutes, the time that is 314 * takes to walk 4 <em>mil</em> at 18 minutes a mil (<em><a href="https://en.wikipedia.org/wiki/Maimonides" 315 * >Rambam</a></em> and others). The sun's position at 72 minutes before {@link #getSunrise sunrise} in Jerusalem 316 * on the <a href="https://kosherjava.com/2022/01/12/equinox-vs-equilux-zmanim-calculations/">around the equinox / 317 * equilux</a> is 16.1° below {@link #GEOMETRIC_ZENITH}. 318 * 319 * @see #ZENITH_16_POINT_1 320 * @see ComplexZmanimCalendar#getAlos16Point1Degrees() 321 * 322 * @return The <code>Date</code> of dawn. If the calculation can't be computed such as northern and southern 323 * locations even south of the Arctic Circle and north of the Antarctic Circle where the sun may not reach 324 * low enough below the horizon for this calculation, a <code>null</code> will be returned. See detailed 325 * explanation on top of the {@link AstronomicalCalendar} documentation. 326 */ 327 public Date getAlosHashachar() { 328 return getSunriseOffsetByDegrees(ZENITH_16_POINT_1); 329 } 330 331 /** 332 * Method to return <em>alos</em> (dawn) calculated using 72 minutes before {@link #getSunrise() sunrise} or 333 * {@link #getSeaLevelSunrise() sea level sunrise} (depending on the {@link #isUseElevation()} setting). This time 334 * is based on the time to walk the distance of 4 <em>Mil</em> at 18 minutes a <em>Mil</em>. The 72 minute time (but 335 * not the concept of fixed minutes) is based on the opinion that the time of the <em>Neshef</em> (twilight between 336 * dawn and sunrise) does not vary by the time of year or location but depends on the time it takes to walk the 337 * distance of 4 <em>Mil</em>. 338 * 339 * @return the <code>Date</code> representing the time. If the calculation can't be computed such as in the Arctic 340 * Circle where there is at least one day a year where the sun does not rise, and one where it does not set, 341 * a <code>null</code> will be returned. See detailed explanation on top of the {@link AstronomicalCalendar} 342 * documentation. 343 */ 344 public Date getAlos72() { 345 return getTimeOffset(getElevationAdjustedSunrise(), -72 * MINUTE_MILLIS); 346 } 347 348 /** 349 * This method returns {@link #getSunTransit() Astronomical <em>chatzos</em>} if the 350 * {@link com.kosherjava.zmanim.util.AstronomicalCalculator calculator} class used supports it and 351 * {@link #isUseAstronomicalChatzos() isUseAstronomicalChatzos()} is set to <em>true</em> or the {@link #getChatzosAsHalfDay() 352 * halfway point between sunrise and sunset} if it does not support it or it is not configured to use it. There are currently 353 * two {@link com.kosherjava.zmanim.util.AstronomicalCalculator calculators} available in the API, the default {@link 354 * com.kosherjava.zmanim.util.NOAACalculator NOAA calculator} and the {@link com.kosherjava.zmanim.util.SunTimesCalculator USNO 355 * calculator}. The USNO calculator calculates <em>chatzos</em> as halfway between sunrise and sunset (identical to six <em>shaaos 356 * zmaniyos</em> after sunrise), while the NOAACalculator calculates it more accurately as {@link #getSunTransit() astronomical 357 * <em>chatzos</em>}. See <a href="https://kosherjava.com/2020/07/02/definition-of-chatzos/">The Definition of <em>Chatzos</em></a> 358 * for a detailed explanation of the ways to calculate <em>Chatzos</em>. Since half-day <em>chatzos</em> can be <code>null</code> in 359 * the Arctic on a day when either sunrise or sunset did not happen and astronomical <em>chatzos</em> can be calculated even in the 360 * Arctic, if half-day <em>chatzos</em> calculates as <code>null</code> and astronomical <em>chatzos</em> is supported by the 361 * calculator, astronomical <em>chatzos</em> will be returned to avoid returning a <code>null</code>. 362 * 363 * @see AstronomicalCalendar#getSunTransit() 364 * @see #getChatzosAsHalfDay() 365 * @see #isUseAstronomicalChatzos() 366 * @see #setUseAstronomicalChatzos(boolean) 367 * @return the <code>Date</code> of <em>chatzos</em>. If the calculation can't be computed such as in the Arctic Circle 368 * 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 369 * support astronomical calculations (that will never report a <code>null</code>) a <code>null</code> will be returned. 370 * See detailed explanation on top of the {@link AstronomicalCalendar} documentation. 371 */ 372 public Date getChatzos() { 373 if(useAstronomicalChatzos) { 374 return getSunTransit(); // can be null of the calculator does not support astronomical chatzos 375 } else { 376 Date halfDayChatzos = getChatzosAsHalfDay(); 377 if(halfDayChatzos == null) { 378 return getSunTransit(); // can be null if the calculator does not support astronomical chatzos 379 } else { 380 return halfDayChatzos; 381 } 382 } 383 } 384 385 /** 386 * Returns <em>chatzos</em> calculated as halfway between sunrise and sunset. Many are of the opinion opinion that 387 * <em>chatzos</em> is calculated as the the midpoint between {@link #getSeaLevelSunrise sea level sunrise} and 388 * {@link #getSeaLevelSunset sea level sunset}, despite it not being the most accurate way to calculate it. A day 389 * starting at <em>alos</em> and ending at <em>tzais</em> using the same time or degree offset will also return 390 * the same time. In reality due to lengthening or shortening of day, this is not necessarily the exact midpoint of 391 * the day, but it is very close. This method allows you to use the NOAACalculator and still calculate <em>chatzos 392 * </em> as six <em>shaaos zmaniyos</em> after sunrise. There are currently two {@link 393 * com.kosherjava.zmanim.util.AstronomicalCalculator calculators} available in the API, the {@link 394 * com.kosherjava.zmanim.util.NOAACalculator} and the {@link com.kosherjava.zmanim.util.SunTimesCalculator}. 395 * The SunTimesCalculator calculates <em>chatzos</em> as halfway between sunrise and sunset (and of six <em>shaaos 396 * zmaniyos</em>), while the NOAACalculator calculates it as astronomical <em>chatzos</em> that is slightly more 397 * accurate. This method allows you to use the NOAACalculator and still calculate <em>chatzos</em> as six <em>shaaos 398 * zmaniyos</em> after sunrise. See <a href="https://kosherjava.com/2020/07/02/definition-of-chatzos/">The Definition 399 * of <em>Chatzos</em></a> for a detailed explanation of the ways to calculate <em>Chatzos</em>. 400 * 401 * @see com.kosherjava.zmanim.util.NOAACalculator#getUTCNoon(Calendar, GeoLocation) 402 * @see com.kosherjava.zmanim.util.SunTimesCalculator#getUTCNoon(Calendar, GeoLocation) 403 * @see com.kosherjava.zmanim.util.AstronomicalCalculator#getUTCNoon(Calendar, GeoLocation) 404 * @see AstronomicalCalendar#getSunTransit(Date, Date) 405 * @see #getChatzos() 406 * @see #getSunTransit() 407 * @see #isUseAstronomicalChatzos() 408 * 409 * @return the <code>Date</code> of the latest <em>chatzos</em>. If the calculation can't be computed such 410 * as in the Arctic Circle where there is at least one day a year where the sun does not rise, and one where 411 * it does not set, a <code>null</code> will be returned. See detailed explanation on top of the 412 * {@link AstronomicalCalendar} documentation. 413 */ 414 public Date getChatzosAsHalfDay() { 415 return getSunTransit(getSeaLevelSunrise(), getSeaLevelSunset()); 416 } 417 418 /** 419 * A generic method for calculating the latest <em>zman krias shema</em> (time to recite shema in the morning) that is 3 * 420 * <em>shaos zmaniyos</em> (temporal hours) after the start of the day, calculated using the start and end of the day passed 421 * to this method. The time from the start of day to the end of day are divided into 12 <em>shaos zmaniyos</em> (temporal 422 * hours), and the latest <em>zman krias shema</em> is calculated as 3 of those <em>shaos zmaniyos</em> after the beginning of 423 * the day. If {@link #isUseAstronomicalChatzosForOtherZmanim()} is <code>true</code>, the 3 <em>shaos zmaniyos</em> will be 424 * based on 1/6 of the time between sunrise and {@link #getSunTransit() astronomical <em>chatzos</em>}. As an example, passing 425 * {@link #getSunrise() sunrise} and {@link #getSunset sunset} or {@link #getSeaLevelSunrise() sea level sunrise} and {@link 426 * #getSeaLevelSunset() sea level sunset} to this method (or {@link #getElevationAdjustedSunrise()} and {@link 427 * #getElevationAdjustedSunset()} that is driven off the {@link #isUseElevation()} setting) will return <em>sof zman krias 428 * shema</em> according to the opinion of the <a href="https://en.wikipedia.org/wiki/Vilna_Gaon">GRA</a>. In cases 429 * where the start and end dates are not synchronous such as in {@link ComplexZmanimCalendar 430 * #getSofZmanShmaAlos16Point1ToTzaisGeonim7Point083Degrees()} <code>false</code> should be passed to the synchronous parameter 431 * to ensure that {@link #isUseAstronomicalChatzosForOtherZmanim()} will not be used. 432 * 433 * @param startOfDay 434 * the start of day for calculating <em>zman krias shema</em>. This can be sunrise or any <em>alos</em> passed 435 * to this method. 436 * @param endOfDay 437 * the end of day for calculating <em>zman krias shema</em>. This can be sunset or any <em>tzais</em> passed to 438 * this method. 439 * @param synchronous 440 * If the <em>zman</em> has a synchronous start and end of the day. If this is <code>false</code>, using a {@link 441 * #isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by 442 * definition <em>chatzos</em> will not be the middle of the day for the <em>zman</em>. 443 * @see #isUseAstronomicalChatzosForOtherZmanim() 444 * @return the <code>Date</code> of the latest <em>zman shema</em> based on the start and end of day times passed to this 445 * method. If the calculation can't be computed such as in the Arctic Circle where there is at least one day 446 * a year where the sun does not rise, and one where it does not set, a <code>null</code> will be returned. See 447 * detailed explanation on top of the {@link AstronomicalCalendar} documentation. 448 */ 449 public Date getSofZmanShma(Date startOfDay, Date endOfDay, boolean synchronous) { 450 if(isUseAstronomicalChatzosForOtherZmanim() && synchronous) { 451 return getHalfDayBasedZman(startOfDay, getChatzos(), 3); 452 } else { 453 return getShaahZmanisBasedZman(startOfDay, endOfDay, 3); 454 } 455 } 456 457 /** 458 * A generic method for calculating the latest <em>zman krias shema</em> that calls {@link #getSofZmanShma(Date, Date, boolean)} 459 * passing <code>false</code> to the synchronous parameter since there is now way to know if the start and end of the day are 460 * synchronous. Passing true when they are not synchronous is too much of a risk. See information on that method for more details. 461 * @param startOfDay 462 * the start of day for calculating <em>zman krias shema</em>. This can be sunrise or any <em>alos</em> passed 463 * to this method. 464 * @param endOfDay 465 * the end of day for calculating <em>zman krias shema</em>. This can be sunset or any <em>tzais</em> passed to 466 * this method. 467 * @return the <code>Date</code> of the latest <em>zman shema</em> based on the start and end of day times passed to this 468 * method. If the calculation can't be computed such as in the Arctic Circle where there is at least one day 469 * a year where the sun does not rise, and one where it does not set, a <code>null</code> will be returned. See 470 * detailed explanation on top of the {@link AstronomicalCalendar} documentation. 471 * @see #getSofZmanShma(Date, Date, boolean) 472 */ 473 public Date getSofZmanShma(Date startOfDay, Date endOfDay) { 474 return getSofZmanShma(startOfDay, endOfDay, false); 475 } 476 477 /** 478 * This method returns the latest <em>zman krias shema</em> (time to recite shema in the morning) that is 3 * 479 * {@link #getShaahZmanisGra() <em>shaos zmaniyos</em>} (solar hours) after {@link #getSunrise() sunrise} or 480 * {@link #getSeaLevelSunrise() sea level sunrise} (depending on the {@link #isUseElevation()} setting), according 481 * to the <a href="https://en.wikipedia.org/wiki/Vilna_Gaon">GRA</a>. 482 * The day is calculated from {@link #getSeaLevelSunrise() sea level sunrise} to {@link #getSeaLevelSunrise sea level 483 * sunset} or {@link #getSunrise() sunrise} to {@link #getSunset() sunset} (depending on the {@link #isUseElevation()} 484 * setting). 485 * 486 * @see #getSofZmanShma(Date, Date) 487 * @see #getShaahZmanisGra() 488 * @see #isUseElevation() 489 * @see ComplexZmanimCalendar#getSofZmanShmaBaalHatanya() 490 * @return the <code>Date</code> of the latest <em>zman shema</em> according to the GRA. If the calculation can't be 491 * computed such as in the Arctic Circle where there is at least one day a year where the sun does not rise, 492 * and one where it does not set, a <code>null</code> will be returned. See the detailed explanation on top 493 * of the {@link AstronomicalCalendar} documentation. 494 */ 495 public Date getSofZmanShmaGRA() { 496 return getSofZmanShma(getElevationAdjustedSunrise(), getElevationAdjustedSunset(), true); 497 } 498 499 /** 500 * This method returns the latest <em>zman krias shema</em> (time to recite shema in the morning) that is 3 * 501 * {@link #getShaahZmanisMGA() <em>shaos zmaniyos</em>} (solar hours) after {@link #getAlos72()}, according to the 502 * <a href="https://en.wikipedia.org/wiki/Avraham_Gombinern">Magen Avraham (MGA)</a>. The day is calculated 503 * from 72 minutes before {@link #getSeaLevelSunrise() sea level sunrise} to 72 minutes after {@link 504 * #getSeaLevelSunrise sea level sunset} or from 72 minutes before {@link #getSunrise() sunrise} to {@link #getSunset() 505 * sunset} (depending on the {@link #isUseElevation()} setting). 506 * 507 * @return the <code>Date</code> of the latest <em>zman shema</em>. If the calculation can't be computed such as in 508 * the Arctic Circle where there is at least one day a year where the sun does not rise, and one where it 509 * does not set, a <code>null</code> will be returned. See detailed explanation on top of the 510 * {@link AstronomicalCalendar} documentation. 511 * @see #getSofZmanShma(Date, Date) 512 * @see ComplexZmanimCalendar#getShaahZmanis72Minutes() 513 * @see ComplexZmanimCalendar#getAlos72() 514 * @see ComplexZmanimCalendar#getSofZmanShmaMGA72Minutes() that 515 */ 516 public Date getSofZmanShmaMGA() { 517 return getSofZmanShma(getAlos72(), getTzais72(), true); 518 } 519 520 /** 521 * This method returns the <em>tzais</em> (nightfall) based on the opinion of <em>Rabbeinu Tam</em> that 522 * <em>tzais hakochavim</em> is calculated as 72 minutes, the time it takes to walk 4 <em>Mil</em> at 18 minutes 523 * a <em>Mil</em>. According to the <a href="https://en.wikipedia.org/wiki/Samuel_Loew">Machtzis Hashekel</a> in 524 * Orach Chaim 235:3, the <a href="https://en.wikipedia.org/wiki/Joseph_ben_Meir_Teomim">Pri Megadim</a> in Orach 525 * Chaim 261:2 (see the Biur Halacha) and others (see Hazmanim Bahalacha 17:3 and 17:5) the 72 minutes are standard 526 * clock minutes any time of the year in any location. Depending on the {@link #isUseElevation()} setting) a 72 527 * minute offset from either {@link #getSunset() sunset} or {@link #getSeaLevelSunset() sea level sunset} is used. 528 * 529 * @see ComplexZmanimCalendar#getTzais16Point1Degrees() 530 * @return the <code>Date</code> representing 72 minutes after sunset. If the calculation can't be 531 * computed such as in the Arctic Circle where there is at least one day a year where the sun does not rise, 532 * and one where it does not set, a <code>null</code> will be returned See detailed explanation on top of the 533 * {@link AstronomicalCalendar} documentation. 534 */ 535 public Date getTzais72() { 536 return getTimeOffset(getElevationAdjustedSunset(), 72 * MINUTE_MILLIS); 537 } 538 539 /** 540 * A method to return candle lighting time, calculated as {@link #getCandleLightingOffset()} minutes before 541 * {@link #getSeaLevelSunset() sea level sunset}. This will return the time for any day of the week, since it can be 542 * used to calculate candle lighting time for <em>Yom Tov</em> (mid-week holidays) as well. Elevation adjustments 543 * are intentionally not performed by this method, but you can calculate it by passing the elevation adjusted sunset 544 * to {@link #getTimeOffset(Date, long)}. 545 * 546 * @return candle lighting time. If the calculation can't be computed such as in the Arctic Circle where there is at 547 * least one day a year where the sun does not rise, and one where it does not set, a <code>null</code> will 548 * be returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. 549 * 550 * @see #getSeaLevelSunset() 551 * @see #getCandleLightingOffset() 552 * @see #setCandleLightingOffset(double) 553 */ 554 public Date getCandleLighting() { 555 return getTimeOffset(getSeaLevelSunset(), -getCandleLightingOffset() * MINUTE_MILLIS); 556 } 557 558 /** 559 * A generic method for calculating the latest <em>zman tfilah</em> (time to recite the morning prayers) 560 * that is 4 * <em>shaos zmaniyos</em> (temporal hours) after the start of the day, calculated using the start and 561 * end of the day passed to this method. 562 * The time from the start of day to the end of day are divided into 12 <em>shaos zmaniyos</em> (temporal hours), 563 * and <em>sof zman tfila</em> is calculated as 4 of those <em>shaos zmaniyos</em> after the beginning of the day. 564 * As an example, passing {@link #getSunrise() sunrise} and {@link #getSunset sunset} or {@link #getSeaLevelSunrise() 565 * sea level sunrise} and {@link #getSeaLevelSunset() sea level sunset} (depending on the {@link #isUseElevation()} 566 * elevation setting) to this method will return <em>zman tfilah</em> according to the opinion of the <a href= 567 * "https://en.wikipedia.org/wiki/Vilna_Gaon">GRA</a>. This method's synchronous parameter indicates if the start 568 * and end of day for the calculation are synchronous, having the same offset. This is typically the case, but some 569 * <em>zmanim</em> calculations are based on a start and end at different offsets from the real start and end of the day, 570 * such as starting the day at <em>alos</em> and an ending it at <em>tzais genoim</em> or some other variant. If the day 571 * is not synchronous a {@link #getHalfDayBasedZman(Date, Date, double) half-day based calculations} will be bypassed. 572 * It would be illogical to use a half-day based calculation that start/end at <em>chatzos</em> when the two "halves" of 573 * the day are not equal, and the halfway point between them is not at <em>chatzos</em>. 574 * 575 * @param startOfDay 576 * the start of day for calculating <em>zman tfilah</em>. This can be sunrise or any <em>alos</em> passed 577 * to this method. 578 * @param endOfDay 579 * the end of day for calculating <em>zman tfilah</em>. This can be sunset or any <em>tzais</em> passed 580 * to this method. 581 * @param synchronous 582 * If the <em>zman</em> has a synchronous start and end of the day. If this is <code>false</code>, using a {@link 583 * #isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by 584 * definition <em>chatzos</em> will not be the middle of the day for the <em>zman</em>. 585 * @return the <code>Date</code> of the latest <em>zman tfilah</em> based on the start and end of day times passed 586 * to this method. If the calculation can't be computed such as in the Arctic Circle where there is at least 587 * one day a year where the sun does not rise, and one where it does not set, a <code>null</code> will be 588 * returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. 589 */ 590 public Date getSofZmanTfila(Date startOfDay, Date endOfDay, boolean synchronous) { 591 if(isUseAstronomicalChatzosForOtherZmanim() && synchronous) { 592 return getHalfDayBasedZman(startOfDay, getChatzos(), 4); 593 } else { 594 return getShaahZmanisBasedZman(startOfDay, endOfDay, 4); 595 } 596 } 597 598 /** 599 * A generic method for calculating the latest <em>zman tfila</em> that calls {@link #getSofZmanTfila(Date, Date, boolean)} 600 * passing <code>false</code> to the synchronous parameter since there is now way to know if the start and end of the day are 601 * synchronous. Passing true when they are not synchronous is too much of a risk. See information on that method for more details. 602 * @param startOfDay 603 * the start of day for calculating <em>zman tfilah</em>. This can be sunrise or any <em>alos</em> passed 604 * to this method. 605 * @param endOfDay 606 * the end of day for calculating <em>zman tfilah</em>. This can be sunset or any <em>tzais</em> passed to 607 * this method. 608 * @return the <code>Date</code> of the latest <em>zman tfilah</em> based on the start and end of day times passed to this 609 * method. If the calculation can't be computed such as in the Arctic Circle where there is at least one day 610 * a year where the sun does not rise, and one where it does not set, a <code>null</code> will be returned. See 611 * detailed explanation on top of the {@link AstronomicalCalendar} documentation. 612 * @see #getSofZmanShma(Date, Date, boolean) 613 */ 614 public Date getSofZmanTfila(Date startOfDay, Date endOfDay) { 615 return getSofZmanTfila(startOfDay, endOfDay, false); 616 } 617 618 /** 619 * This method returns the latest <em>zman tfila</em> (time to recite shema in the morning) that is 4 * 620 * {@link #getShaahZmanisGra() <em>shaos zmaniyos</em> }(solar hours) after {@link #getSunrise() sunrise} or 621 * {@link #getSeaLevelSunrise() sea level sunrise} (depending on the {@link #isUseElevation()} setting), according 622 * to the <a href="https://en.wikipedia.org/wiki/Vilna_Gaon">GRA</a>. 623 * The day is calculated from {@link #getSeaLevelSunrise() sea level sunrise} to {@link #getSeaLevelSunrise sea level 624 * sunset} or {@link #getSunrise() sunrise} to {@link #getSunset() sunset} (depending on the {@link #isUseElevation()} 625 * setting). 626 * 627 * @see #getSofZmanTfila(Date, Date) 628 * @see #getShaahZmanisGra() 629 * @see ComplexZmanimCalendar#getSofZmanTfilaBaalHatanya() 630 * @return the <code>Date</code> of the latest <em>zman tfilah</em>. If the calculation can't be computed such as in 631 * the Arctic Circle where there is at least one day a year where the sun does not rise, and one where it 632 * does not set, a <code>null</code> will be returned. See detailed explanation on top of the 633 * {@link AstronomicalCalendar} documentation. 634 */ 635 public Date getSofZmanTfilaGRA() { 636 return getSofZmanTfila(getElevationAdjustedSunrise(), getElevationAdjustedSunset(), true); 637 } 638 639 /** 640 * This method returns the latest <em>zman tfila</em> (time to recite shema in the morning) that is 4 * 641 * {@link #getShaahZmanisMGA() <em>shaos zmaniyos</em>} (solar hours) after {@link #getAlos72()}, according to the 642 * <em><a href="https://en.wikipedia.org/wiki/Avraham_Gombinern">Magen Avraham (MGA)</a></em>. The day is calculated 643 * from 72 minutes before {@link #getSeaLevelSunrise() sea level sunrise} to 72 minutes after {@link 644 * #getSeaLevelSunrise sea level sunset} or from 72 minutes before {@link #getSunrise() sunrise} to {@link #getSunset() 645 * sunset} (depending on the {@link #isUseElevation()} setting). 646 * 647 * @return the <code>Date</code> of the latest <em>zman tfila</em>. If the calculation can't be computed such as in 648 * the Arctic Circle where there is at least one day a year where the sun does not rise, and one where it 649 * does not set), a <code>null</code> will be returned. See detailed explanation on top of the 650 * {@link AstronomicalCalendar} documentation. 651 * @see #getSofZmanTfila(Date, Date) 652 * @see #getShaahZmanisMGA() 653 * @see #getAlos72() 654 */ 655 public Date getSofZmanTfilaMGA() { 656 return getSofZmanTfila(getAlos72(), getTzais72(), true); 657 } 658 659 /** 660 * A generic method for calculating <em>mincha gedola</em> (the earliest time to recite the <em>mincha1</em> prayers) that 661 * is 6.5 * <em>shaos zmaniyos</em> (temporal hours) after the start of the day, calculated using the start and end of the 662 * 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> 663 * (temporal hours), and <em>mincha gedola</em> is calculated as 6.5 of those <em>shaos zmaniyos</em> after the beginning 664 * of the day. As an example, passing {@link #getSunrise() sunrise} and {@link #getSunset sunset} or {@link 665 * #getSeaLevelSunrise() sea level sunrise} and {@link #getSeaLevelSunset() sea level sunset} (depending on the {@link 666 * #isUseElevation()} elevation setting) to this method will return <em>mincha gedola</em> according to the opinion of the 667 * <a href="https://en.wikipedia.org/wiki/Vilna_Gaon">GRA</a>. Alternatively, this method uses {@link 668 * #isUseAstronomicalChatzosForOtherZmanim()} to control if the time is based on 6.5 <em>sha'os zmaniyos</em> into the day 669 * mentioned above, or as half an hour <em>zmaniyos</em> based on the second half of the day after <em>chatzos</em> ({@link 670 * #getSunTransit() astronomical <em>chatzos</em>} if supported by the {@link AstronomicalCalculator calculator} and {@link 671 * #isUseAstronomicalChatzos() configured} or {@link #getChatzosAsHalfDay() <em>chatzos</em> as half a day} if not. This 672 * method's synchronous parameter indicates if the start and end of day for the calculation are synchronous, having the same 673 * offset. This is typically the case, but some <em>zmanim</em> calculations are based on a start and end at different offsets 674 * 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 genoim</em> 675 * or some other variant. If the day is not synchronous a {@link #getHalfDayBasedZman(Date, Date, double) half-day based 676 * calculations} will be bypassed. It would be illogical to use a half-day based calculation that start/end at <em>chatzos</em> 677 * when the two "halves" of the day are not equal, and the halfway point between them is not at <em>chatzos</em>. 678 * 679 * @param startOfDay 680 * the start of day for calculating <em>Mincha gedola</em>. This can be sunrise or any <em>alos</em> passed 681 * to this method. 682 * @param endOfDay 683 * the end of day for calculating <em>Mincha gedola</em>. This can be sunset or any <em>tzais</em> passed 684 * to this method. 685 * @param synchronous 686 * If the <em>zman</em> has a synchronous start and end of the day. If this is <code>false</code>, using a {@link 687 * #isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by 688 * definition <em>chatzos</em> will not be the middle of the day for the <em>zman</em>. 689 * @return the <code>Date</code> of the time of <em>Mincha gedola</em> based on the start and end of day times 690 * passed to this method. If the calculation can't be computed such as in the Arctic Circle where there is 691 * at least one day a year where the sun does not rise, and one where it does not set, a <code>null</code> will 692 * be returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. 693 * @see #getSunTransit() 694 * @see #getChatzosAsHalfDay() 695 * @see #getChatzos() 696 * @see #isUseAstronomicalChatzos() 697 * @see #isUseAstronomicalChatzosForOtherZmanim() 698 */ 699 public Date getMinchaGedola(Date startOfDay, Date endOfDay, boolean synchronous) { 700 if(isUseAstronomicalChatzosForOtherZmanim() && synchronous) { 701 return getHalfDayBasedZman(getChatzos(), endOfDay, 0.5); 702 } else { 703 return getShaahZmanisBasedZman(startOfDay, endOfDay, 6.5); 704 } 705 } 706 707 /** 708 * A generic method for calculating <em>mincha gedola</em> that calls {@link #getMinchaGedola(Date, Date, boolean)} passing 709 * <code>false</code> to the synchronous parameter since there is now way to know if the start and end of the day are 710 * synchronous. Passing true when they are not synchronous is too much of a risk. See information on that method for more 711 * details. 712 * @param startOfDay 713 * the start of day for calculating <em>Mincha gedola</em>. This can be sunrise or any <em>alos</em> passed 714 * to this method. 715 * @param endOfDay 716 * the end of day for calculating <em>Mincha gedola</em>. This can be sunset or any <em>tzais</em> passed to 717 * this method. 718 * @return the <code>Date</code> of the latest <em>Mincha gedola</em> based on the start and end of day times passed to this 719 * method. If the calculation can't be computed such as in the Arctic Circle where there is at least one day 720 * a year where the sun does not rise, and one where it does not set, a <code>null</code> will be returned. See 721 * detailed explanation on top of the {@link AstronomicalCalendar} documentation. 722 * @see #getMinchaGedola(Date, Date, boolean) 723 */ 724 public Date getMinchaGedola(Date startOfDay, Date endOfDay) { 725 return getMinchaGedola(startOfDay, endOfDay, false); 726 } 727 728 /** 729 * This method returns the latest <em>mincha gedola</em>,the earliest time one can pray <em>mincha</em> that is 6.5 * 730 * {@link #getShaahZmanisGra() <em>shaos zmaniyos</em>} (solar hours) after {@link #getSunrise() sunrise} or 731 * {@link #getSeaLevelSunrise() sea level sunrise} (depending on the {@link #isUseElevation()} setting), according 732 * to the <a href="https://en.wikipedia.org/wiki/Vilna_Gaon">GRA</a>. <em>Mincha gedola</em> is the earliest 733 * time one can pray <em>mincha</em>. The Ramba"m is of the opinion that it is better to delay <em>mincha</em> until 734 * {@link #getMinchaKetana() <em>mincha ketana</em>} while the Ra"sh, Tur, GRA and others are of the 735 * opinion that <em>mincha</em> can be prayed <em>lechatchila</em> starting at <em>mincha gedola</em>. 736 * The day is calculated from {@link #getSeaLevelSunrise() sea level sunrise} to {@link #getSeaLevelSunrise sea level 737 * sunset} or {@link #getSunrise() sunrise} to {@link #getSunset() sunset} (depending on the {@link #isUseElevation()} 738 * setting). 739 * @todo Consider adjusting this to calculate the time as half an hour <em>zmaniyos</em> after either {@link 740 * #getSunTransit() astronomical <em>chatzos</em>} or {@link #getChatzosAsHalfDay() <em>chatzos</em> as half a day} 741 * for {@link AstronomicalCalculator calculators} that support it, based on {@link #isUseAstronomicalChatzos()}. 742 * 743 * @see #getMinchaGedola(Date, Date) 744 * @see #getShaahZmanisGra() 745 * @see #getMinchaKetana() 746 * @see ComplexZmanimCalendar#getMinchaGedolaBaalHatanya() 747 * @return the <code>Date</code> of the time of mincha gedola. If the calculation can't be computed such as in the 748 * Arctic Circle where there is at least one day a year where the sun does not rise, and one where it does 749 * not set, a <code>null</code> will be returned. See detailed explanation on top of the 750 * {@link AstronomicalCalendar} documentation. 751 */ 752 public Date getMinchaGedola() { 753 return getMinchaGedola(getElevationAdjustedSunrise(), getElevationAdjustedSunset(), true); 754 } 755 756 /** 757 * A generic method for calculating <em>samuch lemincha ketana</em>, / near <em>mincha ketana</em> time that is half 758 * an hour before {@link #getMinchaKetana(Date, Date)} or 9 * <em>shaos zmaniyos</em> (temporal hours) after the 759 * start of the day, calculated using the start and end of the day passed to this method. 760 * The time from the start of day to the end of day are divided into 12 <em>shaos zmaniyos</em> (temporal hours), and 761 * <em>samuch lemincha ketana</em> is calculated as 9 of those <em>shaos zmaniyos</em> after the beginning of the day. 762 * For example, passing {@link #getSunrise() sunrise} and {@link #getSunset sunset} or {@link #getSeaLevelSunrise() sea 763 * level sunrise} and {@link #getSeaLevelSunset() sea level sunset} (depending on the {@link #isUseElevation()} elevation 764 * setting) to this method will return <em>samuch lemincha ketana</em> according to the opinion of the 765 * <a href="https://en.wikipedia.org/wiki/Vilna_Gaon">GRA</a>. See the <a href= 766 * "https://hebrewbooks.org/pdfpager.aspx?req=60387&st=&pgnum=294">Mechaber and Mishna Berurah 232</a> and <a href= 767 * "https://hebrewbooks.org/pdfpager.aspx?req=60388&pgnum=34">249:2</a>. 768 * 769 * @param startOfDay 770 * the start of day for calculating <em>samuch lemincha ketana</em>. This can be sunrise or any <em>alos</em> 771 * passed to to this method. 772 * @param endOfDay 773 * the end of day for calculating <em>samuch lemincha ketana</em>. This can be sunset or any <em>tzais</em> 774 * passed to this method. 775 * @param synchronous 776 * If the <em>zman</em> has a synchronous start and end of the day. If this is <code>false</code>, using a {@link 777 * #isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by 778 * definition <em>chatzos</em> will not be the middle of the day for the <em>zman</em>. 779 * @return the <code>Date</code> of the time of <em>Mincha ketana</em> based on the start and end of day times 780 * passed to this method. If the calculation can't be computed such as in the Arctic Circle where there is 781 * at least one day a year where the sun does not rise, and one where it does not set, a <code>null</code> will 782 * be returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. 783 * 784 * @see ComplexZmanimCalendar#getSamuchLeMinchaKetanaGRA() 785 * @see ComplexZmanimCalendar#getSamuchLeMinchaKetana16Point1Degrees() 786 * @see ComplexZmanimCalendar#getSamuchLeMinchaKetana72Minutes() 787 */ 788 public Date getSamuchLeMinchaKetana(Date startOfDay, Date endOfDay, boolean synchronous) { 789 if(isUseAstronomicalChatzosForOtherZmanim() && synchronous) { 790 return getHalfDayBasedZman(getChatzos(), endOfDay, 3); 791 } else { 792 return getShaahZmanisBasedZman(startOfDay, endOfDay, 9); 793 } 794 } 795 796 /** 797 * A generic method for calculating <em>samuch lemincha ketana</em> that calls {@link #getSamuchLeMinchaKetana(Date, Date, boolean)} 798 * passing <code>false</code> to the synchronous parameter since there is now way to know if the start and end of the day are 799 * synchronous. Passing true when they are not synchronous is too much of a risk. See information on that method for more details. 800 * @param startOfDay 801 * the start of day for calculating <em>samuch lemincha ketana</em>. This can be sunrise or any <em>alos</em> 802 * passed to to this method. 803 * @param endOfDay 804 * the end of day for calculating <em>samuch lemincha ketana</em>. This can be sunset or any <em>tzais</em> 805 * passed to this method. 806 * @return the <code>Date</code> of the time of <em>samuch lemincha ketana</em> based on the start and end of day times 807 * passed to this method. If the calculation can't be computed such as in the Arctic Circle where there is 808 * at least one day a year where the sun does not rise, and one where it does not set, a <code>null</code> will 809 * be returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. 810 * @see #getSamuchLeMinchaKetana(Date, Date, boolean) 811 */ 812 public Date getSamuchLeMinchaKetana(Date startOfDay, Date endOfDay) { 813 return getSamuchLeMinchaKetana(startOfDay, endOfDay, false); 814 } 815 816 /** 817 * A generic method for calculating <em>mincha ketana</em>, (the preferred time to recite the mincha prayers in 818 * the opinion of the <em><a href="https://en.wikipedia.org/wiki/Maimonides">Rambam</a></em> and others) that is 819 * 9.5 * <em>shaos zmaniyos</em> (temporal hours) after the start of the day, calculated using the start and end 820 * of the day passed to this method. 821 * The time from the start of day to the end of day are divided into 12 <em>shaos zmaniyos</em> (temporal hours), and 822 * <em>mincha ketana</em> is calculated as 9.5 of those <em>shaos zmaniyos</em> after the beginning of the day. As an 823 * example, passing {@link #getSunrise() sunrise} and {@link #getSunset sunset} or {@link #getSeaLevelSunrise() sea 824 * level sunrise} and {@link #getSeaLevelSunset() sea level sunset} (depending on the {@link #isUseElevation()} 825 * elevation setting) to this method will return <em>mincha ketana</em> according to the opinion of the 826 * <a href="https://en.wikipedia.org/wiki/Vilna_Gaon">GRA</a>. This method's synchronous parameter indicates ifthe start 827 * and end of day for the calculation are synchronous, having the same offset. This is typically the case, but some 828 * <em>zmanim</em> calculations are based on a start and end at different offsets from the real start and end of the day, 829 * such as starting the day at <em>alos</em> and an ending it at <em>tzais genoim</em> or some other variant. If the day 830 * is not synchronous a {@link #getHalfDayBasedZman(Date, Date, double) half-day based calculations} will be bypassed. 831 * It would be illogical to use a half-day based calculation that start/end at <em>chatzos</em> when the two "halves" of 832 * the day are not equal, and the halfway point between them is not at <em>chatzos</em>. 833 * 834 * @param startOfDay 835 * the start of day for calculating <em>Mincha ketana</em>. This can be sunrise or any <em>alos</em> passed 836 * to this method. 837 * @param endOfDay 838 * the end of day for calculating <em>Mincha ketana</em>. This can be sunset or any <em>tzais</em> passed to 839 * this method. 840 * @param synchronous 841 * If the <em>zman</em> has a synchronous start and end of the day. If this is <code>false</code>, using a {@link 842 * #isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by 843 * definition <em>chatzos</em> will not be the middle of the day for the <em>zman</em>. 844 * @return the <code>Date</code> of the time of <em>Mincha ketana</em> based on the start and end of day times 845 * passed to this method. If the calculation can't be computed such as in the Arctic Circle where there is 846 * at least one day a year where the sun does not rise, and one where it does not set, a <code>null</code> will 847 * be returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. 848 */ 849 public Date getMinchaKetana(Date startOfDay, Date endOfDay, boolean synchronous) { 850 if(isUseAstronomicalChatzosForOtherZmanim() && synchronous) { 851 return getHalfDayBasedZman(getChatzos(), endOfDay, 3.5); 852 } else { 853 return getShaahZmanisBasedZman(startOfDay, endOfDay, 9.5); 854 } 855 } 856 857 /** 858 * A generic method for calculating <em>mincha ketana</em> that calls {@link #getMinchaKetana(Date, Date, boolean)} passing 859 * <code>false</code> to the synchronous parameter since there is now way to know if the start and end of the day are synchronous. 860 * Passing true when they are not synchronous is too much of a risk. See information on that method for more details. 861 * @param startOfDay 862 * the start of day for calculating <em>Mincha ketana</em>. This can be sunrise or any <em>alos</em> passed 863 * to this method. 864 * @param endOfDay 865 * the end of day for calculating <em>Mincha ketana</em>. This can be sunset or any <em>tzais</em> passed to 866 * this method. 867 * @return the <code>Date</code> of the time of <em>Mincha ketana</em> based on the start and end of day times 868 * passed to this method. If the calculation can't be computed such as in the Arctic Circle where there is 869 * at least one day a year where the sun does not rise, and one where it does not set, a <code>null</code> will 870 * be returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. 871 * @see #getMinchaKetana(Date, Date, boolean) 872 */ 873 public Date getMinchaKetana(Date startOfDay, Date endOfDay) { 874 return getMinchaKetana(startOfDay, endOfDay, false); 875 } 876 877 /** 878 * This method returns <em>mincha ketana</em>,the preferred earliest time to pray <em>mincha</em> in the 879 * opinion of the <em><a href="https://en.wikipedia.org/wiki/Maimonides">Rambam</a></em> and others, that is 9.5 880 * * {@link #getShaahZmanisGra() <em>shaos zmaniyos</em>} (solar hours) after {@link #getSunrise() sunrise} or 881 * {@link #getSeaLevelSunrise() sea level sunrise} (depending on the {@link #isUseElevation()} setting), according 882 * to the <a href="https://en.wikipedia.org/wiki/Vilna_Gaon">GRA</a>. For more information on this see the 883 * documentation on {@link #getMinchaGedola() <em>mincha gedola</em>}. 884 * The day is calculated from {@link #getSeaLevelSunrise() sea level sunrise} to {@link #getSeaLevelSunrise sea level 885 * sunset} or {@link #getSunrise() sunrise} to {@link #getSunset() sunset} (depending on the {@link #isUseElevation()} 886 * setting. 887 * 888 * @see #getMinchaKetana(Date, Date) 889 * @see #getShaahZmanisGra() 890 * @see #getMinchaGedola() 891 * @see ComplexZmanimCalendar#getMinchaKetanaBaalHatanya() 892 * @return the <code>Date</code> of the time of mincha ketana. If the calculation can't be computed such as in the 893 * Arctic Circle where there is at least one day a year where the sun does not rise, and one where it does 894 * not set, a <code>null</code> will be returned. See detailed explanation on top of the 895 * {@link AstronomicalCalendar} documentation. 896 */ 897 public Date getMinchaKetana() { 898 return getMinchaKetana(getElevationAdjustedSunrise(), getElevationAdjustedSunset(), true); 899 } 900 901 /** 902 * A generic method for calculating <em>plag hamincha</em> (the earliest time that Shabbos can be started) that is 903 * 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 904 * the day passed to the method. 905 * The time from the start of day to the end of day are divided into 12 <em>shaos zmaniyos</em> (temporal hours), and 906 * <em>plag hamincha</em> is calculated as 10.75 of those <em>shaos zmaniyos</em> after the beginning of the day. As an 907 * example, passing {@link #getSunrise() sunrise} and {@link #getSunset sunset} or {@link #getSeaLevelSunrise() sea level 908 * sunrise} and {@link #getSeaLevelSunset() sea level sunset} (depending on the {@link #isUseElevation()} elevation 909 * setting) to this method will return <em>plag mincha</em> according to the opinion of the 910 * <a href="https://en.wikipedia.org/wiki/Vilna_Gaon">GRA</a>. This method's synchronous parameter indicates if the start 911 * and end of day for the calculation are synchronous, having the same offset. This is typically the case, but some 912 * <em>zmanim</em> calculations are based on a start and end at different offsets from the real start and end of the day, 913 * such as starting the day at <em>alos</em> and an ending it at <em>tzais genoim</em> or some other variant. If the day 914 * is not synchronous a {@link #getHalfDayBasedZman(Date, Date, double) half-day based calculations} will be bypassed. It 915 * would be illogical to use a half-day based calculation that start/end at <em>chatzos</em> when the two "halves" of the 916 * day are not equal, and the halfway point between them is not at <em>chatzos</em>. 917 * 918 * @param startOfDay 919 * the start of day for calculating <em>plag hamincha</em>. This can be sunrise or any <em>alos</em> passed to 920 * this method. 921 * @param endOfDay 922 * the end of day for calculating <em>plag hamincha</em>. This can be sunset or any <em>tzais</em> passed to 923 * this method. 924 * @param synchronous 925 * If the <em>zman</em> has a synchronous start and end of the day. If this is <code>false</code>, using a {@link 926 * #isUseAstronomicalChatzosForOtherZmanim()} makes no sense and will be ignored even if set to true, since by 927 * definition <em>chatzos</em> will not be the middle of the day for the <em>zman</em>. 928 * @return the <code>Date</code> of the time of <em>plag hamincha</em> based on the start and end of day times 929 * passed to this method. If the calculation can't be computed such as in the Arctic Circle where there is 930 * at least one day a year where the sun does not rise, and one where it does not set, a <code>null</code> 931 * will be returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. 932 */ 933 public Date getPlagHamincha(Date startOfDay, Date endOfDay, boolean synchronous) { 934 if(isUseAstronomicalChatzosForOtherZmanim() && synchronous) { 935 return getHalfDayBasedZman(getChatzos(), endOfDay, 4.75); 936 } else { 937 return getShaahZmanisBasedZman(startOfDay, endOfDay, 10.75); 938 } 939 } 940 941 /** 942 * A generic method for calculating <em>plag hamincha</em> that calls {@link #getPlagHamincha(Date, Date, boolean)} passing 943 * <code>false</code> to the synchronous parameter since there is no way to know if the start and end of the day are synchronous. 944 * Passing true when they are not synchronous is too much of a risk. See information on that method for more details. 945 * @param startOfDay 946 * the start of day for calculating <em>plag hamincha</em>. This can be sunrise or any <em>alos</em> passed to this method. 947 * @param endOfDay 948 * the end of day for calculating <em>plag hamincha</em>. This can be sunset or any <em>tzais</em> passed to this method. 949 * @return the <code>Date</code> of the time of <em>plag hamincha</em> based on the start and end of day times 950 * passed to this method. If the calculation can't be computed such as in the Arctic Circle where there is 951 * at least one day a year where the sun does not rise, and one where it does not set, a <code>null</code> 952 * will be returned. See detailed explanation on top of the {@link AstronomicalCalendar} documentation. 953 * @see #getPlagHamincha(Date, Date, boolean) 954 */ 955 public Date getPlagHamincha(Date startOfDay, Date endOfDay) { 956 return getPlagHamincha(startOfDay, endOfDay, false); 957 } 958 959 /** 960 * This method returns <em>plag hamincha</em>, that is 10.75 * {@link #getShaahZmanisGra() <em>shaos zmaniyos</em>} 961 * (solar hours) after {@link #getSunrise() sunrise} or {@link #getSeaLevelSunrise() sea level sunrise} (depending on 962 * the {@link #isUseElevation()} setting), according to the <a href="https://en.wikipedia.org/wiki/Vilna_Gaon" 963 * >GRA</a>. <em>Plag hamincha</em> is the earliest time that <em>Shabbos</em> can be started. 964 * The day is calculated from {@link #getSeaLevelSunrise() sea level sunrise} to {@link #getSeaLevelSunrise sea level 965 * sunset} or {@link #getSunrise() sunrise} to {@link #getSunset() sunset} (depending on the {@link #isUseElevation()} 966 * 967 * @see #getPlagHamincha(Date, Date, boolean) 968 * @see #getPlagHamincha(Date, Date) 969 * @see ComplexZmanimCalendar#getPlagHaminchaBaalHatanya() 970 * @return the <code>Date</code> of the time of <em>plag hamincha</em>. If the calculation can't be computed such as 971 * in the Arctic Circle where there is at least one day a year where the sun does not rise, and one where it 972 * does not set, a <code>null</code> will be returned. See detailed explanation on top of the 973 * {@link AstronomicalCalendar} documentation. 974 */ 975 public Date getPlagHamincha() { 976 return getPlagHamincha(getElevationAdjustedSunrise(), getElevationAdjustedSunset(), true); 977 } 978 979 /** 980 * A method that returns a <em>shaah zmanis</em> ({@link #getTemporalHour(Date, Date) temporal hour}) according to 981 * the opinion of the <a href="https://en.wikipedia.org/wiki/Vilna_Gaon">GRA</a>. This calculation divides the day 982 * based on the opinion of the <em>GRA</em> that the day runs from from {@link #getSeaLevelSunrise() sea level 983 * sunrise} to {@link #getSeaLevelSunrise sea level sunset} or {@link #getSunrise() sunrise} to {@link #getSunset() 984 * sunset} (depending on the {@link #isUseElevation()} setting). The day is split into 12 equal parts with each one 985 * being a <em>shaah zmanis</em>. This method is similar to {@link #getTemporalHour}, but can account for elevation. 986 * 987 * @return the <code>long</code> millisecond length of a <em>shaah zmanis</em> calculated from sunrise to sunset. 988 * If the calculation can't be computed such as in the Arctic Circle where there is at least one day a year 989 * where the sun does not rise, and one where it does not set, {@link Long#MIN_VALUE} will be returned. See 990 * detailed explanation on top of the {@link AstronomicalCalendar} documentation. 991 * @see #getTemporalHour(Date, Date) 992 * @see #getSeaLevelSunrise() 993 * @see #getSeaLevelSunset() 994 * @see ComplexZmanimCalendar#getShaahZmanisBaalHatanya() 995 */ 996 public long getShaahZmanisGra() { 997 return getTemporalHour(getElevationAdjustedSunrise(), getElevationAdjustedSunset()); 998 } 999 1000 /** 1001 * A method that returns a <em>shaah zmanis</em> (temporal hour) according to the opinion of the <em><a href= 1002 * "https://en.wikipedia.org/wiki/Avraham_Gombinern">Magen Avraham (MGA)</a></em> based on a 72 minutes <em>alos</em> 1003 * and <em>tzais</em>. This calculation divides the day that runs from dawn to dusk (for <em>sof zman krias shema</em> and 1004 * <em>tfila</em>). Dawn for this calculation is 72 minutes before {@link #getSunrise() sunrise} or {@link #getSeaLevelSunrise() 1005 * sea level sunrise} (depending on the {@link #isUseElevation()} elevation setting) and dusk is 72 minutes after {@link 1006 * #getSunset sunset} or {@link #getSeaLevelSunset() sea level sunset} (depending on the {@link #isUseElevation()} elevation 1007 * setting). This day is split into 12 equal parts with each part being a <em>shaah zmanis</em>. Alternate methods of calculating 1008 * a <em>shaah zmanis</em> according to the Magen Avraham (MGA) are available in the subclass {@link ComplexZmanimCalendar}. 1009 * 1010 * @return the <code>long</code> millisecond length of a <em>shaah zmanis</em>. If the calculation can't be computed 1011 * such as in the Arctic Circle where there is at least one day a year where the sun does not rise, and one 1012 * where it does not set, {@link Long#MIN_VALUE} will be returned. See detailed explanation on top of the 1013 * {@link AstronomicalCalendar} documentation. 1014 */ 1015 public long getShaahZmanisMGA() { 1016 return getTemporalHour(getAlos72(), getTzais72()); 1017 } 1018 1019 /** 1020 * Default constructor will set a default {@link GeoLocation#GeoLocation()}, a default 1021 * {@link AstronomicalCalculator#getDefault() AstronomicalCalculator} and default the calendar to the current date. 1022 * 1023 * @see AstronomicalCalendar#AstronomicalCalendar() 1024 */ 1025 public ZmanimCalendar() { 1026 super(); 1027 } 1028 1029 /** 1030 * A constructor that takes a {@link GeoLocation} as a parameter. 1031 * 1032 * @param location 1033 * the location 1034 */ 1035 public ZmanimCalendar(GeoLocation location) { 1036 super(location); 1037 } 1038 1039 /** 1040 * A method to get the offset in minutes before {@link AstronomicalCalendar#getSeaLevelSunset() sea level sunset} which 1041 * is used in calculating candle lighting time. The default time used is 18 minutes before sea level sunset. Some 1042 * calendars use 15 minutes, while the custom in Jerusalem is to use a 40 minute offset. Please check the local custom 1043 * for candle lighting time. 1044 * 1045 * @return Returns the currently set candle lighting offset in minutes. 1046 * @see #getCandleLighting() 1047 * @see #setCandleLightingOffset(double) 1048 */ 1049 public double getCandleLightingOffset() { 1050 return candleLightingOffset; 1051 } 1052 1053 /** 1054 * A method to set the offset in minutes before {@link AstronomicalCalendar#getSeaLevelSunset() sea level sunset} that is 1055 * used in calculating candle lighting time. The default time used is 18 minutes before sunset. Some calendars use 15 1056 * minutes, while the custom in Jerusalem is to use a 40 minute offset. 1057 * 1058 * @param candleLightingOffset 1059 * The candle lighting offset to set in minutes. 1060 * @see #getCandleLighting() 1061 * @see #getCandleLightingOffset() 1062 */ 1063 public void setCandleLightingOffset(double candleLightingOffset) { 1064 this.candleLightingOffset = candleLightingOffset; 1065 } 1066 1067 /** 1068 * This is a utility method to determine if the current Date (date-time) passed in has a <em>melacha</em> (work) prohibition. 1069 * 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 1070 * class. Sunset is the classes current day's {@link #getElevationAdjustedSunset() elevation adjusted sunset} that observes the 1071 * {@link #isUseElevation()} settings. The {@link JewishCalendar#getInIsrael()} will be set by the inIsrael parameter. 1072 * 1073 * @param currentTime the current time 1074 * @param tzais the time of tzais 1075 * @param inIsrael whether to use Israel holiday scheme or not 1076 * 1077 * @return true if <em>melacha</em> is prohibited or false if it is not. 1078 * 1079 * @see JewishCalendar#isAssurBemelacha() 1080 * @see JewishCalendar#hasCandleLighting() 1081 * @see JewishCalendar#setInIsrael(boolean) 1082 */ 1083 public boolean isAssurBemlacha(Date currentTime, Date tzais, boolean inIsrael) { 1084 JewishCalendar jewishCalendar = new JewishCalendar(); 1085 jewishCalendar.setGregorianDate(getCalendar().get(Calendar.YEAR), getCalendar().get(Calendar.MONTH), 1086 getCalendar().get(Calendar.DAY_OF_MONTH)); 1087 jewishCalendar.setInIsrael(inIsrael); 1088 1089 if(jewishCalendar.hasCandleLighting() && currentTime.compareTo(getElevationAdjustedSunset()) >= 0) { //erev shabbos, YT or YT sheni and after shkiah 1090 return true; 1091 } 1092 1093 if(jewishCalendar.isAssurBemelacha() && currentTime.compareTo(tzais) <= 0) { //is shabbos or YT and it is before tzais 1094 return true; 1095 } 1096 1097 return false; 1098 } 1099 1100 /** 1101 * A generic utility method for calculating any <em>shaah zmanis</em> (temporal hour) based <em>zman</em> with the 1102 * day defined as the start and end of day (or night) and the number of <em>shaahos zmaniyos</em> passed to the 1103 * method. This simplifies the code in other methods such as {@link #getPlagHamincha(Date, Date)} and cuts down on 1104 * code replication. As an example, passing {@link #getSunrise() sunrise} and {@link #getSunset sunset} or {@link 1105 * #getSeaLevelSunrise() sea level sunrise} and {@link #getSeaLevelSunset() sea level sunset} (depending on the 1106 * {@link #isUseElevation()} elevation setting) and 10.75 hours to this method will return <em>plag mincha</em> 1107 * according to the opinion of the <a href="https://en.wikipedia.org/wiki/Vilna_Gaon">GRA</a>. 1108 * 1109 * @param startOfDay 1110 * the start of day for calculating the <em>zman</em>. This can be sunrise or any <em>alos</em> passed 1111 * to this method. 1112 * @param endOfDay 1113 * the end of day for calculating the <em>zman</em>. This can be sunset or any <em>tzais</em> passed to 1114 * this method. 1115 * @param hours 1116 * the number of <em>shaahos zmaniyos</em> (temporal hours) to offset from the start of day 1117 * @return the <code>Date</code> of the time of <em>zman</em> with the <em>shaahos zmaniyos</em> (temporal hours) 1118 * in the day offset from the start of day passed to this method. If the calculation can't be computed such 1119 * as in the Arctic Circle where there is at least one day a year where the sun does not rise, and one 1120 * where it does not set, a <code>null</code> will be returned. See detailed explanation on top of the 1121 * {@link AstronomicalCalendar} documentation. 1122 */ 1123 public Date getShaahZmanisBasedZman(Date startOfDay, Date endOfDay, double hours) { 1124 long shaahZmanis = getTemporalHour(startOfDay, endOfDay); 1125 return getTimeOffset(startOfDay, shaahZmanis * hours); 1126 } 1127 1128 /** 1129 * A utility method that returns the percentage of a <em>shaah zmanis</em> after sunset (or before sunrise) for a given degree 1130 * offset. For the <a href="https://kosherjava.com/2022/01/12/equinox-vs-equilux-zmanim-calculations/">equilux</a> where there 1131 * is a 720-minute day, passing 16.1° for the location of Jerusalem will return about 1.2. This will work for any location 1132 * or date, but will typically only be of interest at the equinox/equilux to calculate the percentage of a <em>shaah zmanis</em> 1133 * 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 1134 * and the <a href="https://en.wikipedia.org/wiki/Hezekiah_da_Silva">Pri Chadash</a> who calculate <em>tzais</em> as a percentage 1135 * 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 1136 * on the equinox / equilux in Israel, this method allows calculations for any degrees level for any location. 1137 * 1138 * @param degrees 1139 * the number of degrees below the horizon after sunset. 1140 * @param sunset 1141 * if <code>true</code> the calculation should be degrees after sunset, or if <code>false</code>, degrees before sunrise. 1142 * @return the <code>double</code> percentage of a <em>sha'ah zmanis</em> for a given set of degrees below the astronomical horizon 1143 * for the current calendar. If the calculation can't be computed a {@link Double#MIN_VALUE} will be returned. See detailed 1144 * explanation on top of the page. 1145 */ 1146 public double getPercentOfShaahZmanisFromDegrees(double degrees, boolean sunset) { 1147 Date seaLevelSunrise = getSeaLevelSunrise(); 1148 Date seaLevelSunset = getSeaLevelSunset(); 1149 Date twilight = null; 1150 if(sunset) { 1151 twilight = getSunsetOffsetByDegrees(GEOMETRIC_ZENITH + degrees); 1152 } else { 1153 twilight = getSunriseOffsetByDegrees(GEOMETRIC_ZENITH + degrees); 1154 } 1155 if(seaLevelSunrise == null || seaLevelSunset == null || twilight == null) { 1156 return Double.MIN_VALUE; 1157 } 1158 double shaahZmanis = (seaLevelSunset.getTime() - seaLevelSunrise.getTime()) / 12.0; 1159 long riseSetToTwilight; 1160 if(sunset) { 1161 riseSetToTwilight = twilight.getTime() - seaLevelSunset.getTime(); 1162 } else { 1163 riseSetToTwilight = seaLevelSunrise.getTime() - twilight.getTime(); 1164 } 1165 return riseSetToTwilight / shaahZmanis; 1166 } 1167 1168 /** 1169 * A utility method to calculate <em>zmanim</em> based on <a href="https://en.wikipedia.org/wiki/Moshe_Feinstein">Rav Moshe 1170 * Feinstein</a> and others as calculated in <a href="https://en.wikipedia.org/wiki/Mesivtha_Tifereth_Jerusalem">MTJ</a>, <a href= 1171 * "https://en.wikipedia.org/wiki/Mesivtha_Tifereth_Jerusalem">Yeshiva of Staten Island</a>, and Camp Yeshiva 1172 * of Staten Island and other calendars. The day is split in two, from <em>alos</em> / sunrise to <em>chatzos</em>, and the 1173 * second half of the day, from <em>chatzos</em> to sunset / <em>tzais</em>. Morning based times are calculated. based on the first 1174 * 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 1175 * <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> 1176 * based on the second half of the day. Some <em>zmanim</em> calculations can be based on subtracting <em>sha'os zmaniyos</em> 1177 * from the end of the day, and that is supported by passing a negative hour to this method. 1178 * 1179 * @param startOfHalfDay 1180 * The start of the half day. This would be <em>alos</em> or sunrise for morning based times such as <em>sof zman krias 1181 * shema</em> and <em>chatzos</em> for afternoon based times such as <em>mincha gedola</em>. 1182 * @param endOfHalfDay 1183 * The end of the half day. This would be <em>chatzos</em> for morning based times such as <em>sof zman krias shema</em> 1184 * and sunset or <em>tzais</em> for afternoon based times such as <em>mincha gedola</em>. 1185 * @param hours 1186 * The number of <em>sha'os zmaniyos</em> (hours) to offset the beginning of the first or second half of the day. For example, 1187 * 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 1188 * hamincha</em>. If the number of hours is negative, it will subtract the number of <em>sha'os zmaniyos</em> from the end 1189 * of the day. 1190 * 1191 * @return the <code>Date</code> of <em>zman</em> based on calculation of the first or second half of the day. If the 1192 * calculation can't be computed such as in the Arctic Circle where there is at least one day a year where the 1193 * sun does not rise, and one where it does not set, a <code>null</code> will be returned. See detailed explanation 1194 * on top of the {@link AstronomicalCalendar} documentation. 1195 * 1196 * @see ComplexZmanimCalendar#getFixedLocalChatzos() 1197 */ 1198 public Date getHalfDayBasedZman(Date startOfHalfDay, Date endOfHalfDay, double hours) { 1199 if (startOfHalfDay == null || endOfHalfDay == null) { 1200 return null; 1201 } 1202 long shaahZmanis = getHalfDayBasedShaahZmanis(startOfHalfDay, endOfHalfDay); 1203 if(shaahZmanis == Long.MIN_VALUE) { //defensive, should not be needed 1204 return null; 1205 } 1206 if(hours >= 0) { // forward from start a day 1207 return getTimeOffset(startOfHalfDay, shaahZmanis * hours); 1208 } else { // subtract from end of day 1209 return getTimeOffset(endOfHalfDay, shaahZmanis * hours); 1210 } 1211 } 1212 1213 /** 1214 * A utility method to calculate the length of a <em>sha'ah zmanis</em> based on 1/6 of a 6 hour day. 1215 * @param startOfHalfDay The start of the half-day. This would be <em>alos</em> or sunrise for the first half of the day, 1216 * or <em>chatzos</em> for the second half of the day. 1217 * @param endOfHalfDay The end of the half-day. This would be <em>chatzos</em> for the first half of the day, or sunset or 1218 * <em>tzais</em> for the second half of the day. 1219 * @return The <code>long</code> millisecond length of a <em>shaah zmanis</em> based on 1/6 of a half-day. If the calculation 1220 * 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, 1221 * and one where it does not set, {@link Long#MIN_VALUE} will be returned. See detailed explanation on top of the 1222 * {@link AstronomicalCalendar} documentation. 1223 * @see #getHalfDayBasedZman(Date, Date, double) 1224 * @see #isUseAstronomicalChatzosForOtherZmanim() 1225 * @todo Consider adjusting various shaah zmanis times to use this. 1226 */ 1227 public long getHalfDayBasedShaahZmanis(Date startOfHalfDay, Date endOfHalfDay) { 1228 if (startOfHalfDay == null || endOfHalfDay == null) { 1229 return Long.MIN_VALUE; 1230 } 1231 return (endOfHalfDay.getTime() - startOfHalfDay.getTime()) / 6; 1232 } 1233}