001 /* 002 * Zmanim Java API 003 * Copyright (C) 2004-2010 Eliyahu Hershfeld 004 * 005 * This program is free software; you can redistribute it and/or modify it under the terms of the 006 * GNU General Public License as published by the Free Software Foundation; either version 2 of the 007 * License, or (at your option) any later version. 008 * 009 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 010 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 011 * General Public License for more details. 012 * 013 * You should have received a copy of the GNU General Public License along with this program; if 014 * not, write to the Free Software Foundation, Inc. 59 Temple Place - Suite 330, Boston, MA 015 * 02111-1307, USA or connect to: http://www.fsf.org/copyleft/gpl.html 016 */ 017 package net.sourceforge.zmanim; 018 019 import java.util.Calendar; 020 import java.util.Date; 021 022 import net.sourceforge.zmanim.util.AstronomicalCalculator; 023 import net.sourceforge.zmanim.util.GeoLocation; 024 025 /** 026 * <p> 027 * Description: A Java library for calculating zmanim. 028 * </p> 029 * The zmanim library is an API is a specialized calendar that can calculate 030 * sunrise and sunset and Jewish <em>zmanim</em> (religious times) for prayers 031 * and other Jewish religious duties. For a much more extensive list of zmanim 032 * use the {@link ComplexZmanimCalendar} that extends this class. This class 033 * contains the main functionality of the Zmanim library. See documentation for 034 * the {@link ComplexZmanimCalendar} and {@link AstronomicalCalendar} for simple 035 * examples on using the API. <h2>Disclaimer:</h2> While I did my best to get 036 * accurate results please do not rely on these zmanim for 037 * <em>halacha lemaaseh</em> 038 * 039 * @author © Eliyahu Hershfeld 2004 - 2010 040 * @version 1.2 041 */ 042 public class ZmanimCalendar extends AstronomicalCalendar { 043 private static final long serialVersionUID = 1; 044 045 /** 046 * The zenith of 16.1° below geometric zenith (90°). This 047 * calculation is used for calculating <em>alos</em> (dawn) and 048 * <em>tzais</em> (nightfall) in some opinions. This calculation is based on 049 * the calculation that the time between dawn and sunrise (and sunset to 050 * nightfall) is the time that is takes to walk 4 <em>mil</em> at 18 minutes 051 * a mil (<em>Ramba"m</em> and others). The sun's position at 72 minutes 052 * before {@link #getSunrise sunrise} in Jerusalem on the equinox is 053 * 16.1° below {@link #GEOMETRIC_ZENITH geometric zenith}. 054 * 055 * @see #getAlosHashachar() 056 * @see ComplexZmanimCalendar#getAlos16Point1Degrees() 057 * @see ComplexZmanimCalendar#getTzais16Point1Degrees() 058 * @see ComplexZmanimCalendar#getSofZmanShmaMGA16Point1Degrees() 059 * @see ComplexZmanimCalendar#getSofZmanTfilaMGA16Point1Degrees() 060 * @see ComplexZmanimCalendar#getMinchaGedola16Point1Degrees() 061 * @see ComplexZmanimCalendar#getMinchaKetana16Point1Degrees() 062 * @see ComplexZmanimCalendar#getPlagHamincha16Point1Degrees() 063 * @see ComplexZmanimCalendar#getPlagAlos16Point1ToTzaisGeonim7Point083Degrees() 064 * @see ComplexZmanimCalendar#getSofZmanShmaAlos16Point1ToSunset() 065 */ 066 protected static final double ZENITH_16_POINT_1 = GEOMETRIC_ZENITH + 16.1; 067 068 /** 069 * The zenith of 8.5° below geometric zenith (90°). This calculation 070 * is used for calculating <em>alos</em> (dawn) and <em>tzais</em> 071 * (nightfall) in some opinions. This calculation is based on the position 072 * of the sun 36 minutes after {@link #getSunset sunset} in Jerusalem on 073 * March 16, about 4 days before the equinox, the day that a solar hour is 074 * one hour, which is 8.5° below {@link #GEOMETRIC_ZENITH geometric 075 * zenith}. The Ohr Meir considers this the time that 3 small starts are 076 * visible, later than the required 3 medium stars. 077 * 078 * @see #getTzais() 079 * @see ComplexZmanimCalendar#getTzaisGeonim8Point5Degrees() 080 */ 081 protected static final double ZENITH_8_POINT_5 = GEOMETRIC_ZENITH + 8.5; 082 083 /** 084 * The default Shabbos candle lighting offset is 18 minutes. This can be 085 * changed via the {@link #setCandleLightingOffset(double)} and retrieved by 086 * the {@link #getCandleLightingOffset()}. 087 */ 088 private double candleLightingOffset = 18; 089 090 /** 091 * Returns <em>tzais</em> (nightfall) when the sun is 8.5° below the 092 * western geometric horizon (90°) after {@link #getSunset sunset}. For 093 * information on the source of this calculation see 094 * {@link #ZENITH_8_POINT_5}. 095 * 096 * @return The <code>Date</code> of nightfall. 097 * @see #ZENITH_8_POINT_5 098 */ 099 public Date getTzais() { 100 return this.getSunsetOffsetByDegrees(ZENITH_8_POINT_5); 101 } 102 103 /** 104 * Returns <em>alos</em> (dawn) based on the time when the sun is 16.1° 105 * below the eastern {@link #GEOMETRIC_ZENITH geometric horizon} before 106 * {@link #getSunrise sunrise}. For more information the source of 16.1° 107 * see {@link #ZENITH_16_POINT_1}. 108 * 109 * @see net.sourceforge.zmanim.ZmanimCalendar#ZENITH_16_POINT_1 110 * @return The <code>Date</code> of dawn. 111 */ 112 public Date getAlosHashachar() { 113 return getSunriseOffsetByDegrees(ZENITH_16_POINT_1); 114 } 115 116 /** 117 * Method to return <em>alos</em> (dawn) calculated using 72 minutes before 118 * {@link #getSeaLevelSunrise() sea level sunrise} (no adjustment for 119 * elevation) based on the time to walk the distance of 4 <em>Mil</em> at 18 120 * minutes a <em>Mil</em>. This is based on the opinion of most 121 * <em>Rishonim</em> who stated that the time of the <em>Neshef</em> (time 122 * between dawn and sunrise) does not vary by the time of year or location 123 * but purely depends on the time it takes to walk the distance of 4 124 * <em>Mil</em>. 125 * 126 * @return the <code>Date</code> representing the time. 127 */ 128 public Date getAlos72() { 129 return getTimeOffset(getSeaLevelSunrise(), -72 * MINUTE_MILLIS); 130 } 131 132 /** 133 * This method returns <em>chatzos</em> (midday) following the opinion of 134 * the GRA that the day for Jewish halachic times start at 135 * {@link #getSunrise sunrise} and ends at {@link #getSunset sunset}. The 136 * returned value is identical to {@link #getSunTransit()} 137 * 138 * @see AstronomicalCalendar#getSunTransit() 139 * @return the <code>Date</code> of chatzos. 140 */ 141 public Date getChatzos() { 142 return getSunTransit(); 143 } 144 145 /** 146 * A method that returns "solar" midnight, or the time when the sun is at 147 * it's <a href="http://en.wikipedia.org/wiki/Nadir">nadir</a>. <br/> 148 * <br/> 149 * <b>Note:</b> this method is experimental and might be removed (or moved) 150 * 151 * @return the <code>Date</code> of Solar Midnight (chatzos layla). 152 */ 153 public Date getSolarMidnight() { 154 ZmanimCalendar clonedCal = (ZmanimCalendar) clone(); 155 clonedCal.getCalendar().add(Calendar.DAY_OF_MONTH, 1); 156 Date sunset = getSunset(); 157 Date sunrise = clonedCal.getSunrise(); 158 return getTimeOffset(sunset, getTemporalHour(sunset, sunrise) * 6); 159 } 160 161 // public Date getChatzosLaylaRSZ() { 162 // ZmanimCalendar clonedCal = (ZmanimCalendar)clone(); 163 // clonedCal.getCalendar().add(Calendar.DAY_OF_MONTH, 1); 164 // Date sunset = getSunset(); 165 // Date sunrise = clonedCal.getAlosHashachar(); 166 // return getTimeOffset(sunset, getTemporalHour(sunset, sunrise) * 6); 167 // } 168 169 /** 170 * This method returns the latest <em>zman krias shema</em> (time to say 171 * Shema in the morning). This time is 3 172 * <em>{@link #getShaahZmanisGra() shaos zmaniyos}</em> (solar hours) after 173 * {@link #getSeaLevelSunrise() sea level sunrise} based on the opinion of 174 * the <em>GR"A</em> and the <em>Baal Hatanya</em> that the day is 175 * calculated from sunrise to sunset. This returns the time 3 * 176 * {@link #getShaahZmanisGra()} after {@link #getSeaLevelSunrise() sea level 177 * sunrise}. 178 * 179 * @see net.sourceforge.zmanim.ZmanimCalendar#getShaahZmanisGra() 180 * @return the <code>Date</code> of the latest zman shema. 181 */ 182 public Date getSofZmanShmaGRA() { 183 return getTimeOffset(getSeaLevelSunrise(), getShaahZmanisGra() * 3); 184 } 185 186 /** 187 * This method returns the latest <em>zman krias shema</em> (time to say 188 * Shema in the morning) in the opinion of the <em>MG"A</em> based on 189 * <em>alos</em> being 72 minutes before {@link #getSunrise() sunrise}. This 190 * time is 3 <em> shaos zmaniyos</em> (solar hours) after dawn based on the 191 * opinion of the <em>MG"A</em> that the day is calculated from a dawn of 72 192 * minutes before sunrise to nightfall of 72 minutes after sunset. This 193 * returns the time of 3 * <em>shaos zmaniyos</em> after dawn. 194 * 195 * @return the <code>Date</code> of the latest zman shema. 196 * @see ComplexZmanimCalendar#getShaahZmanis72Minutes() 197 * @see ComplexZmanimCalendar#getAlos72() 198 * @see ComplexZmanimCalendar#getSofZmanShmaMGA72Minutes() 199 */ 200 public Date getSofZmanShmaMGA() { 201 return getTimeOffset(getAlos72(), getShaahZmanisMGA() * 3); 202 } 203 204 /** 205 * This method returns the <em>tzais</em> (nightfall) based on the opinion 206 * of the <em>Ramba"m</em> and <em>Rabainu Tam</em> that <em>tzais</em> is 207 * calculated as the time it takes to walk 4 <em>Mil</em> at 18 minutes a 208 * <em>Mil</em> for a total of 72 minutes. Even for locations above sea 209 * level, this is calculated at sea level, since the darkness level is not 210 * affected by elevation. 211 * 212 * @return the <code>Date</code> representing 72 minutes after sea level 213 * sunset. 214 */ 215 public Date getTzais72() { 216 return getTimeOffset(getSeaLevelSunset(), 72 * MINUTE_MILLIS); 217 } 218 219 /** 220 * A method to return candle lighting time. This is calculated as 221 * {@link #getCandleLightingOffset()} minutes before sunset. This will 222 * return the time for any day of the week, since it can be used to 223 * calculate candle lighting time for <em>yom tov</em> (holidays) as well. 224 * 225 * @return candle lighting time. 226 * @see #getCandleLightingOffset() 227 * @see #setCandleLightingOffset(double) 228 */ 229 public Date getCandelLighting() { 230 return getTimeOffset(getSunset(), -getCandleLightingOffset() 231 * MINUTE_MILLIS); 232 } 233 234 /** 235 * This method returns the latest 236 * <em>zman tefilah<em> (time to pray morning prayers). This time is 4 237 * hours into the day based on the opinion of the <em>GR"A</em> and the 238 * </em>Baal Hatanya</em> that the day is calculated from sunrise to sunset. 239 * This returns the time 4 * {@link #getShaahZmanisGra()} after 240 * {@link #getSeaLevelSunrise() sea level sunrise}. 241 * 242 * @see net.sourceforge.zmanim.ZmanimCalendar#getShaahZmanisGra() 243 * @return the <code>Date</code> of the latest zman tefilah. 244 */ 245 public Date getSofZmanTfilaGRA() { 246 return getTimeOffset(getSeaLevelSunrise(), getShaahZmanisGra() * 4); 247 } 248 249 /** 250 * This method returns the latest <em>zman tfila</em> (time to say the 251 * morning prayers) in the opinion of the <em>MG"A</em> based on 252 * <em>alos</em> being {@link #getAlos72() 72} minutes before 253 * {@link #getSunrise() sunrise}. This time is 4 254 * <em>{@link #getShaahZmanisMGA() shaos zmaniyos}</em> (temporal hours) 255 * after {@link #getAlos72() dawn} based on the opinion of the <em>MG"A</em> 256 * that the day is calculated from a {@link #getAlos72() dawn} of 72 minutes 257 * before sunrise to {@link #getTzais72() nightfall} of 72 minutes after 258 * sunset. This returns the time of 4 * {@link #getShaahZmanisMGA()} after 259 * {@link #getAlos72() dawn}. 260 * 261 * @return the <code>Date</code> of the latest zman tfila. 262 * @see #getShaahZmanisMGA() 263 * @see #getAlos72() 264 */ 265 public Date getSofZmanTfilaMGA() { 266 return getTimeOffset(getAlos72(), getShaahZmanisMGA() * 4); 267 } 268 269 /** 270 * This method returns the time of <em>mincha gedola</em>. 271 * <em>Mincha gedola</em> is the earliest time one can pray mincha. The 272 * Ramba"m is of the opinion that it is better to delay <em>mincha</em> 273 * until <em>{@link #getMinchaKetana() mincha ketana}</em> while the 274 * <em>Ra"sh, 275 * Tur, GR"A</em> and others are of the opinion that <em>mincha</em> can be 276 * prayed <em>lechatchila</em> starting at <em>mincha gedola</em>. This is 277 * calculated as 6.5 {@link #getShaahZmanisGra() sea level solar hours} 278 * after {@link #getSeaLevelSunrise() sea level sunrise}. This calculation 279 * is calculated based on the opinion of the <em>GR"A</em> and the 280 * <em>Baal Hatanya</em> that the day is calculated from sunrise to sunset. 281 * This returns the time 6.5 {@link #getShaahZmanisGra()} after 282 * {@link #getSeaLevelSunrise() sea level sunrise}. 283 * 284 * @see #getShaahZmanisGra() 285 * @see #getMinchaKetana() 286 * @return the <code>Date</code> of the time of mincha gedola. 287 */ 288 public Date getMinchaGedola() { 289 return getTimeOffset(getSeaLevelSunrise(), getShaahZmanisGra() * 6.5); 290 } 291 292 /** 293 * This method returns the time of <em>mincha ketana</em>. This is the 294 * perfered earliest time to pray <em>mincha</em> in the opinion of the 295 * Ramba"m and others. For more information on this see the documentation on 296 * <em>{@link #getMinchaGedola() mincha gedola}</em>. This is calculated as 297 * 9.5 {@link #getShaahZmanisGra() sea level solar hours} after 298 * {@link #getSeaLevelSunrise() sea level sunrise}. This calculation is 299 * calculated based on the opinion of the <em>GR"A</em> and the 300 * <em>Baal Hatanya</em> that the day is calculated from sunrise to sunset. 301 * This returns the time 9.5 * {@link #getShaahZmanisGra()} after 302 * {@link #getSeaLevelSunrise() sea level sunrise}. 303 * 304 * @see #getShaahZmanisGra() 305 * @see #getMinchaGedola() 306 * @return the <code>Date</code> of the time of mincha gedola. 307 */ 308 public Date getMinchaKetana() { 309 return getTimeOffset(getSeaLevelSunrise(), getShaahZmanisGra() * 9.5); 310 } 311 312 /** 313 * This method returns he time of <em>plag hamincha</em>. This is calculated 314 * as 10.75 hours after sunrise. This calculation is calculated based on the 315 * opinion of the <em>GR"A</em> and the <em>Baal Hatanya</em> that the day 316 * is calculated from sunrise to sunset. This returns the time 10.75 * 317 * {@link #getShaahZmanisGra()} after {@link #getSeaLevelSunrise() sea level 318 * sunrise}. 319 * 320 * @return the <code>Date</code> of the time of <em>plag hamincha</em>. 321 */ 322 public Date getPlagHamincha() { 323 return getTimeOffset(getSeaLevelSunrise(), getShaahZmanisGra() * 10.75); 324 } 325 326 /** 327 * Method to return a <em>shaah zmanis</em> ( 328 * {@link #getTemporalHour(Date, Date) temporal hour}) according to the 329 * opinion of the <em>GR"A</em> and the <em>Baal Hatanya</em>. This 330 * calculation divides the day based on the opinion of the <em>GR"A</em> and 331 * the <em>Baal Hatanya</em> that the day runs from {@link #getSunrise() 332 * sunrise} to {@link #getSunset sunset}. The calculations are based on a 333 * day from {@link #getSeaLevelSunrise() sea level sunrise} to 334 * {@link #getSeaLevelSunset() sea level sunset}. The day is split into 12 335 * equal parts each part with each one being a <em>shaah zmanis</em>. This 336 * method is similar to {@link #getTemporalHour}, but all calculations are 337 * based on a sealevel sunrise and sunset. For additional information, see 338 * Zmanim Kehilchasam, 2nd Edition by Rabbi Dovid Yehuda Burstein, 339 * Jerusalem, 2007. 340 * 341 * @return the <code>long</code> millisecond length of a 342 * <em>shaah zmanis</em>. 343 * @see #getTemporalHour(Date, Date) 344 */ 345 public long getShaahZmanisGra() { 346 return getTemporalHour(getSeaLevelSunrise(), getSeaLevelSunset()); 347 } 348 349 /** 350 * Method to return a <em>shaah zmanis</em> (temporal hour) according to the 351 * opinion of the MGA. This calculation divides the day based on the opinion 352 * of the <em>MGA</em> that the day runs from dawn to dusk (for sof zman 353 * krias shema and tfila). Dawn for this calculation is 72 minutes before 354 * sunrise and dusk is 72 minutes after sunset. This day is split into 12 355 * equal parts with each part being a <em>shaah zmanis</em>. Alternate 356 * mothods of calculating a <em>shaah zmanis</em> are available in the 357 * subclass {@link ComplexZmanimCalendar}. 358 * 359 * @return the <code>long</code> millisecond length of a 360 * <em>shaah zmanis</em>. 361 */ 362 public long getShaahZmanisMGA() { 363 return getTemporalHour(getAlos72(), getTzais72()); 364 } 365 366 /** 367 * Default constructor will set a default {@link GeoLocation#GeoLocation()}, 368 * a default {@link AstronomicalCalculator#getDefault() 369 * AstronomicalCalculator} and default the calendar to the current date. 370 * 371 * @see AstronomicalCalendar#AstronomicalCalendar() 372 */ 373 public ZmanimCalendar() { 374 super(); 375 } 376 377 /** 378 * A constructor that takes a {@link GeoLocation} as a parameter. 379 * 380 * @param location 381 * the location 382 */ 383 public ZmanimCalendar(GeoLocation location) { 384 super(location); 385 } 386 387 /** 388 * @see java.lang.Object#equals(Object) 389 */ 390 public boolean equals(Object object) { 391 if (this == object) { 392 return true; 393 } 394 if (!(object instanceof ZmanimCalendar)) { 395 return false; 396 } 397 ZmanimCalendar zCal = (ZmanimCalendar) object; 398 // return getCalendar().getTime().equals(zCal.getCalendar().getTime()) 399 return getCalendar().equals(zCal.getCalendar()) 400 && getGeoLocation().equals(zCal.getGeoLocation()) 401 && getAstronomicalCalculator().equals( 402 zCal.getAstronomicalCalculator()); 403 } 404 405 /** 406 * @see java.lang.Object#hashCode() 407 */ 408 public int hashCode() { 409 int result = 17; 410 result = 37 * result + getClass().hashCode();// needed or this and 411 // subclasses will 412 // return identical hash 413 result += 37 * result + getCalendar().hashCode(); 414 result += 37 * result + getGeoLocation().hashCode(); 415 result += 37 * result + getAstronomicalCalculator().hashCode(); 416 return result; 417 } 418 419 /** 420 * A method to get the offset in minutes before 421 * {@link AstronomicalCalendar#getSunset() sunset} that is used in 422 * calculating candle lighting time. The default time used is 18 minutes 423 * before sunset. Some calendars use 15 minutes, while the custom in 424 * Jerusalem is to use a 40 minute offset. Please check the local custom for 425 * candel lighting time. 426 * 427 * @return Returns the candle lighting offset to set in minutes.. 428 * @see #getCandelLighting() 429 */ 430 public double getCandleLightingOffset() { 431 return candleLightingOffset; 432 } 433 434 /** 435 * A method to set the offset in minutes before 436 * {@link AstronomicalCalendar#getSunset() sunset} that is used in 437 * calculating candle lighting time. The default time used is 18 minutes 438 * before sunset. Some calendars use 15 minutes, while the custom in 439 * Jerusalem is to use a 40 minute offset. 440 * 441 * @param candleLightingOffset 442 * The candle lighting offset to set in minutes. 443 * @see #getCandelLighting() 444 */ 445 public void setCandleLightingOffset(double candleLightingOffset) { 446 this.candleLightingOffset = candleLightingOffset; 447 } 448 }