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