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