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 }