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 }