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.Date;
020    
021    import net.sourceforge.zmanim.util.AstronomicalCalculator;
022    import net.sourceforge.zmanim.util.GeoLocation;
023    
024    /**
025     * This class extends ZmanimCalendar and provides many more zmanim than
026     * available in the ZmanimCalendar. The basis for most zmanim in this class are
027     * from the <em>sefer</em> <b>Yisroel Vehazmanim</b> by <b>Rabbi Yisroel
028     * Dovid Harfenes</b>. <br />
029     * For an example of the number of different <em>zmanim</em> made available by
030     * this class, there are methods to return 12 different calculations for
031     * <em>alos</em> (dawn) available in this class. The real power of this API is
032     * the ease in calculating <em>zmanim</em> that are not part of the API. The
033     * methods for doing <em>zmanim</em> calculations not present in this or it's
034     * superclass the {@link ZmanimCalendar} are contained in the
035     * {@link AstronomicalCalendar}, the base class of the calendars in our API
036     * since they are generic methods for calculating time based on degrees or time
037     * before or after {@link #getSunrise sunrise} and {@link #getSunset sunset} and
038     * are of interest for calculation beyond <em>zmanim</em> calculations. Here
039     * are some examples: <br />
040     * First create the Calendar for the location you would like to calculate:
041     * 
042     * <pre>
043     * String locationName = &quot;Lakewood, NJ&quot;;
044     * double latitude = 40.0828; //Lakewood, NJ
045     * double longitude = -74.2094; //Lakewood, NJ
046     * double elevation = 0;
047     * //the String parameter in getTimeZone() has to be a valid timezone listed in {@link java.util.TimeZone#getAvailableIDs()}
048     * TimeZone timeZone = TimeZone.getTimeZone(&quot;America/New_York&quot;);
049     * GeoLocation location = new GeoLocation(locationName, latitude, longitude,
050     *              elevation, timeZone);
051     * ComplexZmanimCalendar czc = new ComplexZmanimCalendar(location);
052     * </pre>
053     * 
054     * Note: For locations such as Israel where the beginning and end of daylight
055     * savings time can fluctuate from year to year create a
056     * {@link java.util.SimpleTimeZone} with the known start and end of DST. <br />
057     * To get alos calculated as 14&deg; below the horizon (as calculated in the
058     * calendars published in Montreal) use:
059     * 
060     * <pre>
061     * Date alos14 = czc.getSunriseOffsetByDegrees(14);
062     * </pre>
063     * 
064     * To get <em>mincha gedola</em> calculated based on the MGA using a <em>shaah
065     * zmanis</em>
066     * based on the day starting 16.1&deg; below the horizon (and ending 16.1&deg;
067     * after sunset the following calculation can be used:
068     * 
069     * <pre>
070     * Date minchaGedola = czc.getTimeOffset(czc.getAlos16point1Degrees(), czc
071     *              .getShaahZmanis16Point1Degrees() * 6.5);
072     * </pre>
073     * 
074     * A little more complex example would be calculating <em>plag hamincha</em>
075     * based on a shaah zmanis that was not present in this class. While a drop more
076     * complex it is still rather easy. For example if you wanted to calculate
077     * <em>plag</em> based on the day starting 12&deg; before sunrise and ending
078     * 12&deg; after sunset as calculated in the calendars in Manchester, England
079     * (there is nothing that would prevent your calculating the day using sunrise
080     * and sunset offsets that are not identical degrees, but this would lead to
081     * chatzos being a time other than the {@link #getSunTransit() solar transit}
082     * (solar midday)). The steps involved would be to first calculate the
083     * <em>shaah zmanis</em> and than use that time in milliseconds to calculate
084     * 10.75 hours after sunrise starting at 12&deg; before sunset
085     * 
086     * <pre>
087     * long shaahZmanis = czc.getTemporalHour(czc.getSunriseOffsetByDegrees(12), czc
088     *              .getSunsetOffsetByDegrees(12));
089     * Date plag = getTimeOffset(czc.getSunriseOffsetByDegrees(12),
090     *              shaahZmanis * 10.75);
091     * </pre>
092     * 
093     * <h2>Disclaimer:</h2>
094     * While I did my best to get accurate results please do not rely on these
095     * zmanim for <em>halacha lemaaseh</em>
096     * 
097     * @author &copy; Eliyahu Hershfeld 2004 - 2009
098     * @version 1.1
099     */
100    public class ComplexZmanimCalendar extends ZmanimCalendar {
101            private static final long serialVersionUID = 1;
102    
103            /**
104             * The zenith of 3.7&deg; below {@link #GEOMETRIC_ZENITH  geometric zenith}
105             * (90&deg;). This calculation is used for calculating <em>tzais</em>
106             * (nightfall) according to some opinions. This calculation is based on the
107             * opinion of the Geonim that <em>tzais</em> is the time it takes to walk
108             * 3/4 of a Mil at 18 minutes a Mil, or 13.5 minutes after sunset. The sun
109             * is 3.7&deg below {@link #GEOMETRIC_ZENITH geometric zenith} at this time
110             * in Jerusalem on March 16, about 4 days before the equinox, the day that a
111             * solar hour is one hour.
112             * 
113             * TODO AT see #getTzaisGeonim3Point7Degrees()
114             */
115            protected static final double ZENITH_3_POINT_7 = GEOMETRIC_ZENITH + 3.7;
116    
117            /**
118             * The zenith of 5.95&deg; below {@link #GEOMETRIC_ZENITH  geometric zenith}
119             * (90&deg;). This calculation is used for calculating <em>tzais</em>
120             * (nightfall) according to some opinions. This calculation is based on the
121             * position of the sun 24 minutes after sunset in Jerusalem on March 16,
122             * about 4 days before the equinox, the day that a solar hour is one hour,
123             * which calculates to 5.95&deg; below
124             * {@link #GEOMETRIC_ZENITH geometric zenith}
125             * 
126             * @see #getTzaisGeonim5Point95Degrees()
127             */
128            protected static final double ZENITH_5_POINT_95 = GEOMETRIC_ZENITH + 5.95;
129    
130            /**
131             * The zenith of 7.083&deg; below
132             * {@link #GEOMETRIC_ZENITH  geometric zenith} (90&deg;). This is often
133             * referred to as 7&deg;5' or 7&deg; and 5 minutes. This calculation is used
134             * for calculating <em>alos</em> (dawn) and <em>tzais</em> (nightfall)
135             * according to some opinions. This calculation is based on the position of
136             * the sun 30 minutes after sunset in Jerusalem on March 16, about 4 days
137             * before the equinox, the day that a solar hour is one hour, which
138             * calculates to 7.0833333&deg; below
139             * {@link #GEOMETRIC_ZENITH geometric zenith}. This is time some opinions
140             * consider dark enough for 3 stars to be visible. This is the opinion of
141             * the Shu"t Melamed Leho'il, Shu"t Binyan Tziyon, Tenuvas Sadeh and very
142             * close to the time of the Mekor Chesed on the Sefer chasidim.
143             * 
144             * @see #getTzaisGeonim7Point083Degrees()
145             * @see #getBainHasmashosRT13Point5MinutesBefore7Point083Degrees()
146             */
147            protected static final double ZENITH_7_POINT_083 = GEOMETRIC_ZENITH + 7
148                            + (5 / 60);
149    
150            /**
151             * The zenith of 10.2&deg; below {@link #GEOMETRIC_ZENITH  geometric zenith}
152             * (90&deg;). This calculation is used for calculating <em>misheyakir</em>
153             * according to some opinions. This calculation is based on the position of
154             * the sun 45 minutes before {@link #getSunrise sunrise} in Jerusalem on
155             * March 16, about 4 days before the equinox, the day that a solar hour is
156             * one hour which calculates to 10.2&deg; below
157             * {@link #GEOMETRIC_ZENITH geometric zenith}
158             * 
159             * @see #getMisheyakir10Point2Degrees()
160             */
161            protected static final double ZENITH_10_POINT_2 = GEOMETRIC_ZENITH + 10.2;
162    
163            /**
164             * The zenith of 11&deg; below {@link #GEOMETRIC_ZENITH  geometric zenith}
165             * (90&deg;). This calculation is used for calculating <em>misheyakir</em>
166             * according to some opinions. This calculation is based on the position of
167             * the sun 48 minutes before {@link #getSunrise sunrise} in Jerusalem on
168             * March 16, about 4 days before the equinox, the day that a solar hour is
169             * one hour which calculates to 11&deg; below
170             * {@link #GEOMETRIC_ZENITH geometric zenith}
171             * 
172             * @see #getMisheyakir11Degrees()
173             */
174            protected static final double ZENITH_11_DEGREES = GEOMETRIC_ZENITH + 11;
175    
176            /**
177             * The zenith of 11.5&deg; below {@link #GEOMETRIC_ZENITH  geometric zenith}
178             * (90&deg;). This calculation is used for calculating <em>misheyakir</em>
179             * according to some opinions. This calculation is based on the position of
180             * the sun 52 minutes before {@link #getSunrise sunrise} in Jerusalem on
181             * March 16, about 4 days before the equinox, the day that a solar hour is
182             * one hour which calculates to 11.5&deg; below
183             * {@link #GEOMETRIC_ZENITH geometric zenith}
184             * 
185             * @see #getMisheyakir11Point5Degrees()
186             */
187            protected static final double ZENITH_11_POINT_5 = GEOMETRIC_ZENITH + 11.5;
188    
189            /**
190             * The zenith of 13&deg; below {@link #GEOMETRIC_ZENITH  geometric zenith}
191             * (90&deg;). This calculation is used for calculating
192             * <em>Rabainu Tam's bain hashmashos</em> according to some opinions.
193             * <br/><br/> <b>FIXME:</b> See comments on
194             * {@link #getBainHasmashosRT13Degrees}. This should be changed to 13.2477
195             * after confirmation.
196             * 
197             * @see #getBainHasmashosRT13Degrees
198             * 
199             */
200            protected static final double ZENITH_13_DEGREES = GEOMETRIC_ZENITH + 13;
201    
202            /**
203             * The zenith of 19.8&deg; below {@link #GEOMETRIC_ZENITH  geometric zenith}
204             * (90&deg;). This calculation is used for calculating <em>alos</em>
205             * (dawn) and <em>tzais</em> (nightfall) according to some opinions. This
206             * calculation is based on the position of the sun 90 minutes after sunset
207             * in Jerusalem on March 16, about 4 days before the equinox, the day that a
208             * solar hour is one hour which calculates to 19.8&deg; below
209             * {@link #GEOMETRIC_ZENITH geometric zenith}
210             * 
211             * @see #getTzais19Point8Degrees()
212             * @see #getAlos19Point8Degrees()
213             * @see #getAlos90()
214             * @see #getTzais90()
215             */
216            protected static final double ZENITH_19_POINT_8 = GEOMETRIC_ZENITH + 19.8;
217    
218            /**
219             * The zenith of 26&deg; below {@link #GEOMETRIC_ZENITH  geometric zenith}
220             * (90&deg;). This calculation is used for calculating <em>alos</em>
221             * (dawn) and <em>tzais</em> (nightfall) according to some opinions. This
222             * calculation is based on the position of the sun
223             * {@link #getAlos120() 120 minutes} after sunset in Jerusalem on March 16,
224             * about 4 days before the equinox, the day that a solar hour is one hour
225             * which calculates to 26&deg; below
226             * {@link #GEOMETRIC_ZENITH geometric zenith}
227             * 
228             * @see #getAlos26Degrees()
229             * @see #getTzais26Degrees()
230             * @see #getAlos120()
231             * @see #getTzais120()
232             */
233            protected static final double ZENITH_26_DEGREES = GEOMETRIC_ZENITH + 26.0;
234    
235            private double ateretTorahSunsetOffset = 40;
236    
237            public ComplexZmanimCalendar(GeoLocation location) {
238                    super(location);
239            }
240    
241            /**
242             * Default constructor will set a default {@link GeoLocation#GeoLocation()},
243             * a default
244             * {@link AstronomicalCalculator#getDefault() AstronomicalCalculator} and
245             * default the calendar to the current date.
246             * 
247             * @see AstronomicalCalendar#AstronomicalCalendar()
248             */
249            public ComplexZmanimCalendar() {
250                    super();
251            }
252    
253            /**
254             * Method to return a <em>shaah zmanis</em> (temporal hour) calculated
255             * using a 19.8&deg; dip. This calculation divides the day based on the
256             * opinion of the MGA that the day runs from dawn to dusk. Dawn for this
257             * calculation is when the sun is 19.8&deg; below the eastern geometric
258             * horizon before sunrise. Dusk for this is when the sun is 19.8&deg; below
259             * the western geometric horizon after sunset. This day is split into 12
260             * equal parts with each part being a <em>shaah zmanis</em>.
261             * 
262             * @return the <code>long</code> millisecond length of a
263             *         <em>shaah zmanis</em>.
264             */
265            public long getShaahZmanis19Point8Degrees() {
266                    return getTemporalHour(getAlos19Point8Degrees(),
267                                    getTzais19Point8Degrees());
268            }
269    
270            /**
271             * Method to return a <em>shaah zmanis</em> (temporal hour) calculated
272             * using a 18&deg; dip. This calculation divides the day based on the
273             * opinion of the MGA that the day runs from dawn to dusk. Dawn for this
274             * calculation is when the sun is 18&deg; below the eastern geometric
275             * horizon before sunrise. Dusk for this is when the sun is 18&deg; below
276             * the western geometric horizon after sunset. This day is split into 12
277             * equal parts with each part being a <em>shaah zmanis</em>.
278             * 
279             * @return the <code>long</code> millisecond length of a
280             *         <em>shaah zmanis</em>.
281             */
282            public long getShaahZmanis18Degrees() {
283                    return getTemporalHour(getAlos18Degrees(), getTzais18Degrees());
284            }
285    
286            /**
287             * Method to return a <em>shaah zmanis</em> (temporal hour) calculated
288             * using a dip of 26&deg;. This calculation divides the day based on the
289             * opinion of the MGA that the day runs from dawn to dusk. Dawn for this
290             * calculation is when the sun is {@link #getAlos26Degrees() 26&deg;} below
291             * the eastern geometric horizon before sunrise. Dusk for this is when the
292             * sun is {@link #getTzais26Degrees() 26&deg;} below the western geometric
293             * horizon after sunset. This day is split into 12 equal parts with each
294             * part being a <em>shaah zmanis</em>.
295             * 
296             * @return the <code>long</code> millisecond length of a
297             *         <em>shaah zmanis</em>.
298             */
299            public long getShaahZmanis26Degrees() {
300                    return getTemporalHour(getAlos26Degrees(), getTzais26Degrees());
301            }
302    
303            /**
304             * Method to return a <em>shaah zmanis</em> (temporal hour) calculated
305             * using a dip of 16.1&deg;. This calculation divides the day based on the
306             * opinion that the day runs from dawn to dusk. Dawn for this calculation is
307             * when the sun is 16.1&deg; below the eastern geometric horizon before
308             * sunrise and dusk is when the sun is 16.1&deg; below the western geometric
309             * horizon after sunset. This day is split into 12 equal parts with each
310             * part being a <em>shaah zmanis</em>.
311             * 
312             * @return the <code>long</code> millisecond length of a
313             *         <em>shaah zmanis</em>.
314             * @see #getAlos16Point1Degrees()
315             * @see #getTzais16Point1Degrees()
316             * @see #getSofZmanShmaMGA16Point1Degrees()
317             * @see #getSofZmanTfilaMGA16Point1Degrees()
318             * @see #getMinchaGedola16Point1Degrees()
319             * @see #getMinchaKetana16Point1Degrees()
320             * @see #getPlagHamincha16Point1Degrees()
321             */
322    
323            public long getShaahZmanis16Point1Degrees() {
324                    return getTemporalHour(getAlos16Point1Degrees(),
325                                    getTzais16Point1Degrees());
326            }
327    
328            /**
329             * Method to return a <em>shaah zmanis</em> (solar hour) according to the
330             * opinion of the MGA. This calculation divides the day based on the opinion
331             * of the <em>MGA</em> that the day runs from dawn to dusk. Dawn for this
332             * calculation is 60 minutes before sunrise and dusk is 60 minutes after
333             * sunset. This day is split into 12 equal parts with each part being a
334             * <em>shaah zmanis</em>. Alternate mothods of calculating a
335             * <em>shaah zmanis</em> are available in the subclass
336             * {@link ComplexZmanimCalendar}
337             * 
338             * @return the <code>long</code> millisecond length of a
339             *         <em>shaah zmanis</em>.
340             */
341            public long getShaahZmanis60Minutes() {
342                    return getTemporalHour(getAlos60(), getTzais60());
343            }
344    
345            /**
346             * Method to return a <em>shaah zmanis</em> (solar hour) according to the
347             * opinion of the MGA. This calculation divides the day based on the opinion
348             * of the <em>MGA</em> that the day runs from dawn to dusk. Dawn for this
349             * calculation is 72 minutes before sunrise and dusk is 72 minutes after
350             * sunset. This day is split into 12 equal parts with each part being a
351             * <em>shaah zmanis</em>. Alternate mothods of calculating a
352             * <em>shaah zmanis</em> are available in the subclass
353             * {@link ComplexZmanimCalendar}
354             * 
355             * @return the <code>long</code> millisecond length of a
356             *         <em>shaah zmanis</em>.
357             */
358            public long getShaahZmanis72Minutes() {
359                    return getShaahZmanisMGA();
360            }
361    
362            /**
363             * Method to return a <em>shaah zmanis</em> (temporal hour) according to
364             * the opinion of the MGA based on <em>alos</em> being
365             * {@link #getAlos72Zmanis() 72} minutes <em>zmaniyos</em> before
366             * {@link #getSunrise() sunrise}. This calculation divides the day based on
367             * the opinion of the <em>MGA</em> that the day runs from dawn to dusk.
368             * Dawn for this calculation is 72 minutes <em>zmaniyos</em> before
369             * sunrise and dusk is 72 minutes <em>zmaniyos</em> after sunset. This day
370             * is split into 12 equal parts with each part being a <em>shaah zmanis</em>.
371             * This is identical to 1/10th of the day from {@link #getSunrise() sunrise}
372             * to {@link #getSunset() sunset}.
373             * 
374             * @return the <code>long</code> millisecond length of a
375             *         <em>shaah zmanis</em>.
376             * @see #getAlos72Zmanis()
377             * @see #getTzais72Zmanis()
378             */
379            public long getShaahZmanis72MinutesZmanis() {
380                    return getTemporalHour(getAlos72Zmanis(), getTzais72Zmanis());
381            }
382    
383            /**
384             * Method to return a <em>shaah zmanis</em> (temporal hour) calculated
385             * using a dip of 90 minutes. This calculation divides the day based on the
386             * opinion of the MGA that the day runs from dawn to dusk. Dawn for this
387             * calculation is 90 minutes before sunrise and dusk is 90 minutes after
388             * sunset. This day is split into 12 equal parts with each part being a
389             * <em>shaah zmanis</em>.
390             * 
391             * @return the <code>long</code> millisecond length of a
392             *         <em>shaah zmanis</em>.
393             */
394            public long getShaahZmanis90Minutes() {
395                    return getTemporalHour(getAlos90(), getTzais90());
396            }
397    
398            /**
399             * Method to return a <em>shaah zmanis</em> (temporal hour) according to
400             * the opinion of the MGA based on <em>alos</em> being
401             * {@link #getAlos90Zmanis() 90} minutes <em>zmaniyos</em> before
402             * {@link #getSunrise() sunrise}. This calculation divides the day based on
403             * the opinion of the <em>MGA</em> that the day runs from dawn to dusk.
404             * Dawn for this calculation is 90 minutes <em>zmaniyos</em> before
405             * sunrise and dusk is 90 minutes <em>zmaniyos</em> after sunset. This day
406             * is split into 12 equal parts with each part being a <em>shaah zmanis</em>.
407             * This is identical to 1/8th of the day from {@link #getSunrise() sunrise}
408             * to {@link #getSunset() sunset}.
409             * 
410             * @return the <code>long</code> millisecond length of a
411             *         <em>shaah zmanis</em>.
412             * @see #getAlos90Zmanis()
413             * @see #getTzais90Zmanis()
414             */
415            public long getShaahZmanis90MinutesZmanis() {
416                    return getTemporalHour(getAlos90Zmanis(), getTzais90Zmanis());
417            }
418    
419            /**
420             * Method to return a <em>shaah zmanis</em> (temporal hour) according to
421             * the opinion of the MGA based on <em>alos</em> being
422             * {@link #getAlos96Zmanis() 96} minutes <em>zmaniyos</em> before
423             * {@link #getSunrise() sunrise}. This calculation divides the day based on
424             * the opinion of the <em>MGA</em> that the day runs from dawn to dusk.
425             * Dawn for this calculation is 96 minutes <em>zmaniyos</em> before
426             * sunrise and dusk is 96 minutes <em>zmaniyos</em> after sunset. This day
427             * is split into 12 equal parts with each part being a <em>shaah zmanis</em>.
428             * This is identical to 1/7.5th of the day from
429             * {@link #getSunrise() sunrise} to {@link #getSunset() sunset}.
430             * 
431             * @return the <code>long</code> millisecond length of a
432             *         <em>shaah zmanis</em>.
433             * @see #getAlos96Zmanis()
434             * @see #getTzais96Zmanis()
435             */
436            public long getShaahZmanis96MinutesZmanis() {
437                    return getTemporalHour(getAlos96Zmanis(), getTzais96Zmanis());
438            }
439    
440            /**
441             * Method to return a <em>shaah zmanis</em> (temporal hour) according to
442             * the opinion of the Chacham Yosef Harari-Raful of Yeshivat Ateret Torah
443             * calculated with <em>alos</em> being 1/10th of sunrise to sunset day, or
444             * {@link #getAlos72Zmanis() 72} minutes <em>zmaniyos</em> of such a day
445             * before {@link #getSunrise() sunrise}, and tzais is usually calculated as
446             * {@link #getTzaisAteretTorah() 40 minutes} after
447             * {@link #getSunset() sunset}. This day is split into 12 equal parts with
448             * each part being a <em>shaah zmanis</em>. Note that with this system,
449             * chatzos (mid-day) will not be the point that the sun is
450             * {@link #getSunTransit() halfway across the sky}.
451             * 
452             * @return the <code>long</code> millisecond length of a
453             *         <em>shaah zmanis</em>.
454             * @see #getAlos72Zmanis()
455             * @see #getTzaisAteretTorah()
456             * @see #getAteretTorahSunsetOffset()
457             * @see #setAteretTorahSunsetOffset(double)
458             */
459            public long getShaahZmanisAteretTorah() {
460                    return getTemporalHour(getAlos72Zmanis(), getTzaisAteretTorah());
461            }
462    
463            /**
464             * Method to return a <em>shaah zmanis</em> (temporal hour) calculated
465             * using a dip of 96 minutes. This calculation divides the day based on the
466             * opinion of the MGA that the day runs from dawn to dusk. Dawn for this
467             * calculation is 96 minutes before sunrise and dusk is 96 minutes after
468             * sunset. This day is split into 12 equal parts with each part being a
469             * <em>shaah zmanis</em>.
470             * 
471             * @return the <code>long</code> millisecond length of a
472             *         <em>shaah zmanis</em>.
473             */
474            public long getShaahZmanis96Minutes() {
475                    return getTemporalHour(getAlos96(), getTzais96());
476            }
477    
478            /**
479             * Method to return a <em>shaah zmanis</em> (temporal hour) calculated
480             * using a dip of 120 minutes. This calculation divides the day based on the
481             * opinion of the MGA that the day runs from dawn to dusk. Dawn for this
482             * calculation is 120 minutes before sunrise and dusk is 120 minutes after
483             * sunset. This day is split into 12 equal parts with each part being a
484             * <em>shaah zmanis</em>.
485             * 
486             * @return the <code>long</code> millisecond length of a
487             *         <em>shaah zmanis</em>.
488             */
489            public long getShaahZmanis120Minutes() {
490                    return getTemporalHour(getAlos120(), getTzais120());
491            }
492    
493            /**
494             * Method to return a <em>shaah zmanis</em> (temporal hour) according to
495             * the opinion of the MGA based on <em>alos</em> being
496             * {@link #getAlos120Zmanis() 120} minutes <em>zmaniyos</em> before
497             * {@link #getSunrise() sunrise}. This calculation divides the day based on
498             * the opinion of the <em>MGA</em> that the day runs from dawn to dusk.
499             * Dawn for this calculation is 120 minutes <em>zmaniyos</em> before
500             * sunrise and dusk is 120 minutes <em>zmaniyos</em> after sunset. This
501             * day is split into 12 equal parts with each part being a
502             * <em>shaah zmanis</em>. This is identical to 1/6th of the day from
503             * {@link #getSunrise() sunrise} to {@link #getSunset() sunset}.
504             * 
505             * @return the <code>long</code> millisecond length of a
506             *         <em>shaah zmanis</em>.
507             * @see #getAlos120Zmanis()
508             * @see #getTzais120Zmanis()
509             */
510            public long getShaahZmanis120MinutesZmanis() {
511                    return getTemporalHour(getAlos120Zmanis(), getTzais120Zmanis());
512            }
513    
514            /**
515             * This method returns the time of <em>plag hamincha</em>. This is
516             * calculated as 10.75 hours after {@link #getAlos96Zmanis() dawn}. The
517             * formula used is:<br/> 10.75 * {@link #getShaahZmanis96MinutesZmanis()}
518             * after {@link #getAlos96Zmanis() dawn}.
519             * 
520             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
521             */
522            public Date getPlagHamincha120MinutesZmanis() {
523                    return getTimeOffset(getAlos120Zmanis(),
524                                    getShaahZmanis120MinutesZmanis() * 10.75);
525            }
526    
527            /**
528             * This method returns the time of <em>plag hamincha</em>. This is
529             * calculated as 10.75 hours after {@link #getAlos72() dawn}. The formula
530             * used is:<br/> 10.75 *{@link #getShaahZmanis72Minutes()} after
531             * {@link #getAlos72()}.
532             * 
533             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
534             */
535            public Date getPlagHamincha120Minutes() {
536                    return getTimeOffset(getAlos120(), getShaahZmanis120Minutes() * 10.75);
537            }
538    
539            /**
540             * Method to return <em>alos</em> (dawn) calculated using 60 minutes
541             * before {@link #getSeaLevelSunrise() sea level sunrise} on the time to
542             * walk the distance of 4 <em>Mil</em> at 15 minutes a <em>Mil</em> (the
543             * opinion of the Chavas Yair. See the Divray Malkiel). This is based on the
544             * opinion of most <em>Rishonim</em> who stated that the time of the
545             * <em>Neshef</em> (time between dawn and sunrise) does not vary by the
546             * time of year or location but purely depends on the time it takes to walk
547             * the distance of 4 <em>Mil</em>.
548             * 
549             * @return the <code>Date</code> representing the time.
550             */
551            public Date getAlos60() {
552                    return getTimeOffset(getSeaLevelSunrise(), -60 * MINUTE_MILLIS);
553            }
554    
555            /**
556             * Method to return <em>alos</em> (dawn) calculated using 72 minutes
557             * <em>zmaniyos</em>( <em>GR"A</em> and the <em>Baal Hatanya</em>)
558             * or 1/10th of the day before sea level sunrise. This is based on an 18
559             * minute <em>Mil</em> so the time for 4 <em>Mil</em> is 72 minutes
560             * which is 1/10th of a day (12 * 60 = 720) based on the day starting at
561             * {@link #getSeaLevelSunrise() sea level sunrise} and ending at
562             * {@link #getSeaLevelSunset() sea level sunset}. The actual alculation is
563             * {@link #getSeaLevelSunrise()}- ( {@link #getShaahZmanisGra()} * 1.2).
564             * This calculation is used in the calendars published by
565             * <em>Hisachdus Harabanim D'Artzos Habris Ve'Kanada</em>
566             * 
567             * @return the <code>Date</code> representing the time.
568             * @see #getShaahZmanisGra()
569             */
570            public Date getAlos72Zmanis() {
571                    long shaahZmanis = getShaahZmanisGra();
572                    if (shaahZmanis == Long.MIN_VALUE) {
573                            return null;
574                    }
575                    return getTimeOffset(getSeaLevelSunrise(), (long) (shaahZmanis * -1.2));
576            }
577    
578            /**
579             * Method to return <em>alos</em> (dawn) calculated using 96 minutes
580             * before {@link #getSeaLevelSunrise() sea level sunrise} based on the time
581             * to walk the distance of 4 <em>Mil</em> at 24 minutes a <em>Mil</em>.
582             * This is based on the opinion of most <em>Rishonim</em> who stated that
583             * the time of the <em>Neshef</em> (time between dawn and sunrise) does
584             * not vary by the time of year or location but purely depends on the time
585             * it takes to walk the distance of 4 <em>Mil</em>.
586             * 
587             * @return the <code>Date</code> representing the time.
588             */
589            public Date getAlos96() {
590                    return getTimeOffset(getSeaLevelSunrise(), -96 * MINUTE_MILLIS);
591            }
592    
593            /**
594             * Method to return <em>alos</em> (dawn) calculated using 90 minutes
595             * <em>zmaniyos</em>( <em>GR"A</em> and the <em>Baal Hatanya</em>)
596             * or 1/8th of the day before sea level sunrise. This is based on a 22.5
597             * minute <em>Mil</em> so the time for 4 <em>Mil</em> is 90 minutes
598             * which is 1/8th of a day (12 * 60 = 720) /8 =90 based on the day starting
599             * at {@link #getSunrise() sunrise} and ending at
600             * {@link #getSunset() sunset}. The actual calculation is
601             * {@link #getSunrise()} - ({@link #getShaahZmanisGra()} * 1.5).
602             * 
603             * @return the <code>Date</code> representing the time.
604             * @see #getShaahZmanisGra()
605             */
606            public Date getAlos90Zmanis() {
607                    long shaahZmanis = getShaahZmanisGra();
608                    if (shaahZmanis == Long.MIN_VALUE) {
609                            return null;
610                    }
611                    return getTimeOffset(getSeaLevelSunrise(), (long) (shaahZmanis * -1.5));
612            }
613    
614            /**
615             * Method to return <em>alos</em> (dawn) calculated using 90 minutes
616             * <em>zmaniyos</em>( <em>GR"A</em> and the <em>Baal Hatanya</em>)
617             * or 1/8th of the day before sea level sunrise. This is based on a 24
618             * minute <em>Mil</em> so the time for 4 <em>Mil</em> is 90 minutes
619             * which is 1/7.5th of a day (12 * 60 = 720) / 7.5 =96 based on the day
620             * starting at {@link #getSunrise() sunrise} and ending at
621             * {@link #getSunset() sunset}. The actual calculation is
622             * {@link #getSunrise()} - ({@link #getShaahZmanisGra()} * 1.6).
623             * 
624             * @return the <code>Date</code> representing the time.
625             * @see #getShaahZmanisGra()
626             */
627            public Date getAlos96Zmanis() {
628                    long shaahZmanis = getShaahZmanisGra();
629                    if (shaahZmanis == Long.MIN_VALUE) {
630                            return null;
631                    }
632                    return getTimeOffset(getSeaLevelSunrise(), (long) (shaahZmanis * -1.6));
633            }
634    
635            /**
636             * Method to return <em>alos</em> (dawn) calculated using 90 minutes
637             * before {@link #getSeaLevelSunrise() sea level sunrise} on the time to
638             * walk the distance of 4 <em>Mil</em> at 22.5 minutes a <em>Mil</em>.
639             * This is based on the opinion of most <em>Rishonim</em> who stated that
640             * the time of the <em>Neshef</em> (time between dawn and sunrise) does
641             * not vary by the time of year or location but purely depends on the time
642             * it takes to walk the distance of 4 <em>Mil</em>.
643             * 
644             * @return the <code>Date</code> representing the time.
645             */
646            public Date getAlos90() {
647                    return getTimeOffset(getSeaLevelSunrise(), -90 * MINUTE_MILLIS);
648            }
649    
650            /**
651             * Method to return <em>alos</em> (dawn) calculated using 120 minutes
652             * before {@link #getSeaLevelSunrise() sea level sunrise} (no adjustment for
653             * elevation is made) based on the time to walk the distance of 5
654             * <em>Mil</em>( <em>Ula</em>) at 24 minutes a <em>Mil</em>. This
655             * is based on the opinion of most <em>Rishonim</em> who stated that the
656             * time of the <em>Neshef</em> (time between dawn and sunrise) does not
657             * vary by the time of year or location but purely depends on the time it
658             * takes to walk the distance of 5 <em>Mil</em>(<em>Ula</em>).
659             * 
660             * @return the <code>Date</code> representing the time.
661             */
662            public Date getAlos120() {
663                    return getTimeOffset(getSeaLevelSunrise(), -120 * MINUTE_MILLIS);
664            }
665    
666            /**
667             * Method to return <em>alos</em> (dawn) calculated using 120 minutes
668             * <em>zmaniyos</em>( <em>GR"A</em> and the <em>Baal Hatanya</em>)
669             * or 1/6th of the day before sea level sunrise. This is based on a 24
670             * minute <em>Mil</em> so the time for 5 <em>Mil</em> is 120 minutes
671             * which is 1/6th of a day (12 * 60 = 720) / 6 =120 based on the day
672             * starting at {@link #getSunrise() sunrise} and ending at
673             * {@link #getSunset() sunset}. The actual calculation is
674             * {@link #getSunrise()} - ({@link #getShaahZmanisGra()} * 2).
675             * 
676             * @return the <code>Date</code> representing the time.
677             * @see #getShaahZmanisGra()
678             */
679            public Date getAlos120Zmanis() {
680                    long shaahZmanis = getShaahZmanisGra();
681                    if (shaahZmanis == Long.MIN_VALUE) {
682                            return null;
683                    }
684                    return getTimeOffset(getSeaLevelSunrise(), shaahZmanis * -2);
685            }
686    
687            /**
688             * Method to return <em>alos</em> (dawn) calculated when the sun is
689             * {@link #ZENITH_26_DEGREES 26&deg;} below the eastern geometric horizon
690             * before sunrise. This calculation is based on the same calculation of
691             * {@link #getAlos120() 120 minutes} but uses a degree based calculation
692             * instead of 120 exact minutes. This calculation is based on the position
693             * of the sun 120 minutes before sunrise in Jerusalem in the equinox which
694             * calculates to 26&deg; below {@link #GEOMETRIC_ZENITH geometric zenith}.
695             * 
696             * @return the <code>Date</code> representing <em>alos</em>.
697             * @see #ZENITH_26_DEGREES
698             * @see #getAlos120()
699             * @see #getTzais120()
700             */
701            public Date getAlos26Degrees() {
702                    return getSunriseOffsetByDegrees(ZENITH_26_DEGREES);
703            }
704    
705            /**
706             * to return <em>alos</em> (dawn) calculated when the sun is
707             * {@link #ASTRONOMICAL_ZENITH 18&deg;} below the eastern geometric horizon
708             * before sunrise.
709             * 
710             * @return the <code>Date</code> representing <em>alos</em>.
711             * @see #ASTRONOMICAL_ZENITH
712             */
713            public Date getAlos18Degrees() {
714                    return getSunriseOffsetByDegrees(ASTRONOMICAL_ZENITH);
715            }
716    
717            /**
718             * Method to return <em>alos</em> (dawn) calculated when the sun is
719             * {@link #ZENITH_19_POINT_8 19.8&deg;} below the eastern geometric horizon
720             * before sunrise. This calculation is based on the same calculation of
721             * {@link #getAlos90() 90 minutes} but uses a degree based calculation
722             * instead of 90 exact minutes. This calculation is based on the position of
723             * the sun 90 minutes before sunrise in Jerusalem in the equinox which
724             * calculates to 19.8&deg; below {@link #GEOMETRIC_ZENITH geometric zenith}
725             * 
726             * @return the <code>Date</code> representing <em>alos</em>.
727             * @see #ZENITH_19_POINT_8
728             * @see #getAlos90()
729             */
730            public Date getAlos19Point8Degrees() {
731                    return getSunriseOffsetByDegrees(ZENITH_19_POINT_8);
732            }
733    
734            /**
735             * Method to return <em>alos</em> (dawn) calculated when the sun is
736             * {@link #ZENITH_16_POINT_1 16.1&deg;} below the eastern geometric horizon
737             * before sunrise. This calculation is based on the same calculation of
738             * {@link #getAlos72() 72 minutes} but uses a degree based calculation
739             * instead of 72 exact minutes. This calculation is based on the position of
740             * the sun 72 minutes before sunrise in Jerusalem in the equinox which
741             * calculates to 16.1&deg; below {@link #GEOMETRIC_ZENITH geometric zenith}.
742             * 
743             * @return the <code>Date</code> representing <em>alos</em>.
744             * @see #ZENITH_16_POINT_1
745             * @see #getAlos72()
746             */
747            public Date getAlos16Point1Degrees() {
748                    return getSunriseOffsetByDegrees(ZENITH_16_POINT_1);
749            }
750    
751            /**
752             * This method returns <em>misheyakir</em> based on the position of the
753             * sun when it is {@link #ZENITH_11_DEGREES 11.5&deg;} below
754             * {@link #GEOMETRIC_ZENITH  geometric zenith} (90&deg;). This calculation
755             * is used for calculating <em>misheyakir</em> according to some opinions.
756             * This calculation is based on the position of the sun 52 minutes before
757             * {@link #getSunrise sunrise}in Jerusalem in the equinox which calculates
758             * to 11.5&deg; below {@link #GEOMETRIC_ZENITH geometric zenith}
759             * 
760             * @see #ZENITH_11_POINT_5
761             */
762            public Date getMisheyakir11Point5Degrees() {
763                    return getSunriseOffsetByDegrees(ZENITH_11_POINT_5);
764            }
765    
766            /**
767             * This method returns <em>misheyakir</em> based on the position of the
768             * sun when it is {@link #ZENITH_11_DEGREES 11&deg;} below
769             * {@link #GEOMETRIC_ZENITH  geometric zenith} (90&deg;). This calculation
770             * is used for calculating <em>misheyakir</em> according to some opinions.
771             * This calculation is based on the position of the sun 48 minutes before
772             * {@link #getSunrise sunrise}in Jerusalem in the equinox which calculates
773             * to 11&deg; below {@link #GEOMETRIC_ZENITH geometric zenith}
774             * 
775             * @see #ZENITH_11_DEGREES
776             */
777            public Date getMisheyakir11Degrees() {
778                    return getSunriseOffsetByDegrees(ZENITH_11_DEGREES);
779            }
780    
781            /**
782             * This method returns <em>misheyakir</em> based on the position of the
783             * sun when it is {@link #ZENITH_10_POINT_2 10.2&deg;} below
784             * {@link #GEOMETRIC_ZENITH  geometric zenith} (90&deg;). This calculation
785             * is used for calculating <em>misheyakir</em> according to some opinions.
786             * This calculation is based on the position of the sun 45 minutes before
787             * {@link #getSunrise sunrise} in Jerusalem in the equinox which calculates
788             * to 10.2&deg; below {@link #GEOMETRIC_ZENITH geometric zenith}
789             * 
790             * @see #ZENITH_10_POINT_2
791             */
792            public Date getMisheyakir10Point2Degrees() {
793                    return getSunriseOffsetByDegrees(ZENITH_10_POINT_2);
794            }
795    
796            /**
797             * This method returns the latest <em>zman krias shema</em> (time to say
798             * Shema in the morning) in the opinion of the <em>MG"A</em> based on
799             * <em>alos</em> being {@link #getAlos19Point8Degrees()() 19.8&deg;}
800             * before {@link #getSunrise() sunrise}. This time is 3
801             * <em>{@link #getShaahZmanis19Point8Degrees() shaos zmaniyos}</em> (solar
802             * hours) after {@link #getAlos19Point8Degrees() dawn} based on the opinion
803             * of the <em>MG"A</em> that the day is calculated from dawn to nightfall
804             * with both being 19.8&deg; below sunrise or sunset. This returns the time
805             * of 3 *{@link #getShaahZmanis19Point8Degrees()} after
806             * {@link #getAlos19Point8Degrees() dawn}.
807             * 
808             * @return the <code>Date</code> of the latest zman shema.
809             * @see #getShaahZmanis19Point8Degrees()
810             * @see #getAlos19Point8Degrees()
811             */
812            public Date getSofZmanShmaMGA19Point8Degrees() {
813                    return getTimeOffset(getAlos19Point8Degrees(),
814                                    getShaahZmanis19Point8Degrees() * 3);
815            }
816    
817            /**
818             * This method returns the latest <em>zman krias shema</em> (time to say
819             * Shema in the morning) in the opinion of the <em>MG"A</em> based on
820             * <em>alos</em> being {@link #getAlos16Point1Degrees()() 16.1&deg;}
821             * before {@link #getSunrise() sunrise}. This time is 3
822             * <em>{@link #getShaahZmanis16Point1Degrees() shaos zmaniyos}</em> (solar
823             * hours) after {@link #getAlos16Point1Degrees() dawn} based on the opinion
824             * of the <em>MG"A</em> that the day is calculated from dawn to nightfall
825             * with both being 16.1&deg; below sunrise or sunset. This returns the time
826             * of 3 *{@link #getShaahZmanis16Point1Degrees()} after
827             * {@link #getAlos16Point1Degrees() dawn}.
828             * 
829             * @return the <code>Date</code> of the latest zman shema.
830             * @see #getShaahZmanis16Point1Degrees()
831             * @see #getAlos16Point1Degrees()
832             */
833            public Date getSofZmanShmaMGA16Point1Degrees() {
834                    return getTimeOffset(getAlos16Point1Degrees(),
835                                    getShaahZmanis16Point1Degrees() * 3);
836            }
837    
838            /**
839             * This method returns the latest <em>zman krias shema</em> (time to say
840             * Shema in the morning) in the opinion of the <em>MG"A</em> based on
841             * <em>alos</em> being {@link #getAlos72() 72} minutes before
842             * {@link #getSunrise() sunrise}. This time is 3
843             * <em>{@link #getShaahZmanis72Minutes() shaos zmaniyos}</em> (solar
844             * hours) after {@link #getAlos72() dawn} based on the opinion of the
845             * <em>MG"A</em> that the day is calculated from a
846             * {@link #getAlos72() dawn} of 72 minutes before sunrise to
847             * {@link #getTzais72() nightfall} of 72 minutes after sunset. This returns
848             * the time of 3 * {@link #getShaahZmanis72Minutes()} after
849             * {@link #getAlos72() dawn}. This class returns an identical time to
850             * {@link #getSofZmanShmaMGA()} and is repeated here for clarity.
851             * 
852             * @return the <code>Date</code> of the latest zman shema.
853             * @see #getShaahZmanis72Minutes()
854             * @see #getAlos72()
855             * @see #getSofZmanShmaMGA()
856             */
857            public Date getSofZmanShmaMGA72Minutes() {
858                    return getSofZmanShmaMGA();
859            }
860    
861            /**
862             * This method returns the latest <em>zman krias shema</em> (time to say
863             * Shema in the morning) in the opinion of the <em>MG"A</em> based on
864             * <em>alos</em> being {@link #getAlos72Zmanis() 72} minutes
865             * <em>zmaniyos</em>, or 1/10th of the day before
866             * {@link #getSunrise() sunrise}. This time is 3
867             * <em>{@link #getShaahZmanis90MinutesZmanis() shaos zmaniyos}</em> (solar
868             * hours) after {@link #getAlos72Zmanis() dawn} based on the opinion of the
869             * <em>MG"A</em> that the day is calculated from a
870             * {@link #getAlos72Zmanis() dawn} of 72 minutes <em>zmaniyos</em>, or
871             * 1/10th of the day before {@link #getSeaLevelSunrise() sea level sunrise}
872             * to {@link #getTzais72Zmanis() nightfall} of 72 minutes <em>zmaniyos</em>
873             * after {@link #getSeaLevelSunset() sea level sunset}. This returns the
874             * time of 3 * {@link #getShaahZmanis72MinutesZmanis()} after
875             * {@link #getAlos72Zmanis() dawn}.
876             * 
877             * @return the <code>Date</code> of the latest zman shema.
878             * @see #getShaahZmanis72MinutesZmanis()
879             * @see #getAlos72Zmanis()
880             */
881            public Date getSofZmanShmaMGA72MinutesZmanis() {
882                    return getTimeOffset(getAlos72Zmanis(),
883                                    getShaahZmanis72MinutesZmanis() * 3);
884            }
885    
886            /**
887             * This method returns the latest <em>zman krias shema</em> (time to say
888             * Shema in the morning) in the opinion of the <em>MG"A</em> based on
889             * <em>alos</em> being {@link #getAlos90() 90} minutes before
890             * {@link #getSunrise() sunrise}. This time is 3
891             * <em>{@link #getShaahZmanis90Minutes() shaos zmaniyos}</em> (solar
892             * hours) after {@link #getAlos90() dawn} based on the opinion of the
893             * <em>MG"A</em> that the day is calculated from a
894             * {@link #getAlos90() dawn} of 90 minutes before sunrise to
895             * {@link #getTzais90() nightfall} of 90 minutes after sunset. This returns
896             * the time of 3 * {@link #getShaahZmanis90Minutes()} after
897             * {@link #getAlos90() dawn}.
898             * 
899             * @return the <code>Date</code> of the latest zman shema.
900             * @see #getShaahZmanis90Minutes()
901             * @see #getAlos90()
902             */
903            public Date getSofZmanShmaMGA90Minutes() {
904                    return getTimeOffset(getAlos90(), getShaahZmanis90Minutes() * 3);
905            }
906    
907            /**
908             * This method returns the latest <em>zman krias shema</em> (time to say
909             * Shema in the morning) in the opinion of the <em>MG"A</em> based on
910             * <em>alos</em> being {@link #getAlos90Zmanis() 90} minutes
911             * <em>zmaniyos</em> before {@link #getSunrise() sunrise}. This time is 3
912             * <em>{@link #getShaahZmanis90MinutesZmanis() shaos zmaniyos}</em> (solar
913             * hours) after {@link #getAlos90Zmanis() dawn} based on the opinion of the
914             * <em>MG"A</em> that the day is calculated from a
915             * {@link #getAlos90Zmanis() dawn} of 90 minutes <em>zmaniyos</em> before
916             * sunrise to {@link #getTzais90Zmanis() nightfall} of 90 minutes
917             * <em>zmaniyos</em> after sunset. This returns the time of 3 *
918             * {@link #getShaahZmanis90MinutesZmanis()} after
919             * {@link #getAlos90Zmanis() dawn}.
920             * 
921             * @return the <code>Date</code> of the latest zman shema.
922             * @see #getShaahZmanis90MinutesZmanis()
923             * @see #getAlos90Zmanis()
924             */
925            public Date getSofZmanShmaMGA90MinutesZmanis() {
926                    return getTimeOffset(getAlos90Zmanis(),
927                                    getShaahZmanis90MinutesZmanis() * 3);
928            }
929    
930            /**
931             * This method returns the latest <em>zman krias shema</em> (time to say
932             * Shema in the morning) in the opinion of the <em>MG"A</em> based on
933             * <em>alos</em> being {@link #getAlos96() 96} minutes before
934             * {@link #getSunrise() sunrise}. This time is 3
935             * <em>{@link #getShaahZmanis96Minutes() shaos zmaniyos}</em> (solar
936             * hours) after {@link #getAlos96() dawn} based on the opinion of the
937             * <em>MG"A</em> that the day is calculated from a
938             * {@link #getAlos96() dawn} of 96 minutes before sunrise to
939             * {@link #getTzais96() nightfall} of 96 minutes after sunset. This returns
940             * the time of 3 * {@link #getShaahZmanis96Minutes()} after
941             * {@link #getAlos96() dawn}.
942             * 
943             * @return the <code>Date</code> of the latest zman shema.
944             * @see #getShaahZmanis96Minutes()
945             * @see #getAlos96()
946             */
947            public Date getSofZmanShmaMGA96Minutes() {
948                    return getTimeOffset(getAlos96(), getShaahZmanis96Minutes() * 3);
949            }
950    
951            /**
952             * This method returns the latest <em>zman krias shema</em> (time to say
953             * Shema in the morning) in the opinion of the <em>MG"A</em> based on
954             * <em>alos</em> being {@link #getAlos90Zmanis() 96} minutes
955             * <em>zmaniyos</em> before {@link #getSunrise() sunrise}. This time is 3
956             * <em>{@link #getShaahZmanis96MinutesZmanis() shaos zmaniyos}</em> (solar
957             * hours) after {@link #getAlos96Zmanis() dawn} based on the opinion of the
958             * <em>MG"A</em> that the day is calculated from a
959             * {@link #getAlos96Zmanis() dawn} of 96 minutes <em>zmaniyos</em> before
960             * sunrise to {@link #getTzais90Zmanis() nightfall} of 96 minutes
961             * <em>zmaniyos</em> after sunset. This returns the time of 3 *
962             * {@link #getShaahZmanis96MinutesZmanis()} after
963             * {@link #getAlos96Zmanis() dawn}.
964             * 
965             * @return the <code>Date</code> of the latest zman shema.
966             * @see #getShaahZmanis96MinutesZmanis()
967             * @see #getAlos96Zmanis()
968             */
969            public Date getSofZmanShmaMGA96MinutesZmanis() {
970                    return getTimeOffset(getAlos96Zmanis(),
971                                    getShaahZmanis96MinutesZmanis() * 3);
972            }
973    
974            /**
975             * This method returns the latest <em>zman krias shema</em> (time to say
976             * Shema in the morning) calculated as 3 hours (regular and not zmaniyos)
977             * before {@link ZmanimCalendar#getChatzos()}. This is the opinion of the
978             * <em>Shach</em> in the
979             * <em>Nekudas Hakesef (Yora Deah 184), Shevus Yaakov, Chasan Sofer</em>
980             * and others.This returns the time of 3 hours before
981             * {@link ZmanimCalendar#getChatzos()}.
982             * 
983             * @return the <code>Date</code> of the latest zman shema.
984             * @see ZmanimCalendar#getChatzos()
985             * @see #getSofZmanTfila2HoursBeforeChatzos()
986             */
987            public Date getSofZmanShma3HoursBeforeChatzos() {
988                    return getTimeOffset(getChatzos(), -180 * MINUTE_MILLIS);
989            }
990    
991            /**
992             * This method returns the latest <em>zman krias shema</em> (time to say
993             * Shema in the morning) in the opinion of the <em>MG"A</em> based on
994             * <em>alos</em> being {@link #getAlos120() 120} minutes or 1/6th of the
995             * day before {@link #getSunrise() sunrise}. This time is 3
996             * <em>{@link #getShaahZmanis120Minutes() shaos zmaniyos}</em> (solar
997             * hours) after {@link #getAlos120() dawn} based on the opinion of the
998             * <em>MG"A</em> that the day is calculated from a
999             * {@link #getAlos120() dawn} of 120 minutes before sunrise to
1000             * {@link #getTzais120() nightfall} of 120 minutes after sunset. This
1001             * returns the time of 3 *{@link #getShaahZmanis120Minutes()} after
1002             * {@link #getAlos120() dawn}.
1003             * 
1004             * @return the <code>Date</code> of the latest zman shema.
1005             * @see #getShaahZmanis120Minutes()
1006             * @see #getAlos120()
1007             */
1008            public Date getSofZmanShmaMGA120Minutes() {
1009                    return getTimeOffset(getAlos120(), getShaahZmanis120Minutes() * 3);
1010            }
1011    
1012            /**
1013             * This method returns the latest <em>zman krias shema</em> (time to say
1014             * Shema in the morning) based on the opinion that the day starts at
1015             * <em>{@link #getAlos16Point1Degrees() alos 16.1&deg;}</em> and ends at
1016             * {@link #getSunset() sunset}. 3 shaos zmaniyos are calculated based on
1017             * this day and added to {@link #getAlos16Point1Degrees() alos}to reach
1018             * this time. This time is 3 <em>shaos zmaniyos</em> (solar hours) after
1019             * {@link #getAlos16Point1Degrees() dawn} based on the opinion that the day
1020             * is calculated from a {@link #getAlos16Point1Degrees() alos 16.1&deg;} to
1021             * {@link #getSunset() sunset}.<br />
1022             * <b>Note: </b> Based on this calculation <em>chatzos</em> will not be at
1023             * midday.
1024             * 
1025             * @return the <code>Date</code> of the latest zman shema based on this
1026             *         day.
1027             * @see #getAlos16Point1Degrees()
1028             * @see #getSunset()
1029             */
1030            public Date getSofZmanShmaAlos16Point1ToSunset() {
1031                    long shaahZmanis = getTemporalHour(getAlos16Point1Degrees(),
1032                                    getSunset());
1033                    return getTimeOffset(getAlos16Point1Degrees(), shaahZmanis * 3);
1034            }
1035    
1036            /**
1037             * This method returns the latest <em>zman krias shema</em> (time to say
1038             * Shema in the morning) based on the opinion that the day starts at
1039             * <em>{@link #getAlos16Point1Degrees() alos 16.1&deg;}</em> and ends at
1040             * {@link #getTzaisGeonim7Point083Degrees() tzais 7.083&deg;}. 3
1041             * <em>shaos zmaniyos</em> are calculated based on this day and added to
1042             * {@link #getAlos16Point1Degrees() alos} to reach this time. This time is 3
1043             * <em>shaos zmaniyos</em> (temporal hours) after
1044             * {@link #getAlos16Point1Degrees() alos 16.1&deg;} based on the opinion
1045             * that the day is calculated from a
1046             * {@link #getAlos16Point1Degrees() alos 16.1&deg;} to
1047             * <em>{@link #getTzaisGeonim7Point083Degrees() tzais 7.083&deg;}</em>.<br />
1048             * <b>Note: </b> Based on this calculation <em>chatzos</em> will not be at
1049             * midday.
1050             * 
1051             * @return the <code>Date</code> of the latest zman shema based on this
1052             *         calculation.
1053             * @see #getAlos16Point1Degrees()
1054             * @see #getTzaisGeonim7Point083Degrees()
1055             */
1056            public Date getSofZmanShmaAlos16Point1ToTzaisGeonim7Point083Degrees() {
1057                    long shaahZmanis = getTemporalHour(getAlos16Point1Degrees(),
1058                                    getTzaisGeonim7Point083Degrees());
1059                    return getTimeOffset(getAlos16Point1Degrees(), shaahZmanis * 3);
1060            }
1061    
1062            /**
1063             * From the GR"A in Kol Eliyahu on Berachos #173 that states that zman krias
1064             * shema is calculated as half the time from sunrise to fixed local chatzos.
1065             * The GR"A himself seems to contradic this when he stated that zman krias
1066             * shema is 1/4 of the day from sunrise to sunset. See Sarah Lamoed #25 in
1067             * Yisroel Vehazmanim Vol III page 1016.
1068             * 
1069             * @return the <code>Date</code> of the latest zman shema based on this
1070             *         calculation.
1071             * @see #getFixedLocalChatzos()
1072             */
1073            public Date getSofZmanShmaKolEliyahu() {
1074                    Date chatzos = getFixedLocalChatzos();
1075                    if (chatzos == null || getSunrise() == null) {
1076                            return null;
1077                    }
1078                    long diff = (chatzos.getTime() - getSunrise().getTime()) / 2;
1079                    return getTimeOffset(chatzos, -diff);
1080            }
1081    
1082            /**
1083             * This method returns the latest <em>zman tfila</em> (time to say the
1084             * morning prayers) in the opinion of the <em>MG"A</em> based on
1085             * <em>alos</em> being {@link #getAlos19Point8Degrees()() 19.8&deg;}
1086             * before {@link #getSunrise() sunrise}. This time is 4
1087             * <em>{@link #getShaahZmanis19Point8Degrees() shaos zmaniyos}</em> (solar
1088             * hours) after {@link #getAlos19Point8Degrees() dawn} based on the opinion
1089             * of the <em>MG"A</em> that the day is calculated from dawn to nightfall
1090             * with both being 19.8&deg; below sunrise or sunset. This returns the time
1091             * of 4 *{@link #getShaahZmanis19Point8Degrees()} after
1092             * {@link #getAlos19Point8Degrees() dawn}.
1093             * 
1094             * @return the <code>Date</code> of the latest zman shema.
1095             * 
1096             * @see #getShaahZmanis19Point8Degrees()
1097             * @see #getAlos19Point8Degrees()
1098             */
1099            public Date getSofZmanTfilaMGA19Point8Degrees() {
1100                    return getTimeOffset(getAlos19Point8Degrees(),
1101                                    getShaahZmanis19Point8Degrees() * 4);
1102            }
1103    
1104            /**
1105             * This method returns the latest <em>zman tfila</em> (time to say the
1106             * morning prayers) in the opinion of the <em>MG"A</em> based on
1107             * <em>alos</em> being {@link #getAlos19Point8Degrees()() 16.1&deg;}
1108             * before {@link #getSunrise() sunrise}. This time is 4
1109             * <em>{@link #getShaahZmanis16Point1Degrees() shaos zmaniyos}</em> (solar
1110             * hours) after {@link #getAlos16Point1Degrees() dawn} based on the opinion
1111             * of the <em>MG"A</em> that the day is calculated from dawn to nightfall
1112             * with both being 16.1&deg; below sunrise or sunset. This returns the time
1113             * of 4 *{@link #getShaahZmanis16Point1Degrees()} after
1114             * {@link #getAlos16Point1Degrees() dawn}.
1115             * 
1116             * @return the <code>Date</code> of the latest zman shema.
1117             * 
1118             * @see #getShaahZmanis16Point1Degrees()
1119             * @see #getAlos16Point1Degrees()
1120             */
1121            public Date getSofZmanTfilaMGA16Point1Degrees() {
1122                    return getTimeOffset(getAlos16Point1Degrees(),
1123                                    getShaahZmanis16Point1Degrees() * 4);
1124            }
1125    
1126            /**
1127             * This method returns the latest <em>zman tfila</em> (time to say the
1128             * morning prayers) in the opinion of the <em>MG"A</em> based on
1129             * <em>alos</em> being {@link #getAlos72() 72} minutes before
1130             * {@link #getSunrise() sunrise}. This time is 4
1131             * <em>{@link #getShaahZmanis72Minutes() shaos zmaniyos}</em> (solar
1132             * hours) after {@link #getAlos72() dawn} based on the opinion of the
1133             * <em>MG"A</em> that the day is calculated from a
1134             * {@link #getAlos72() dawn} of 72 minutes before sunrise to
1135             * {@link #getTzais72() nightfall} of 72 minutes after sunset. This returns
1136             * the time of 4 * {@link #getShaahZmanis72Minutes()} after
1137             * {@link #getAlos72() dawn}. This class returns an identical time to
1138             * {@link #getSofZmanTfilaMGA()} and is repeated here for clarity.
1139             * 
1140             * @return the <code>Date</code> of the latest zman tfila.
1141             * @see #getShaahZmanis72Minutes()
1142             * @see #getAlos72()
1143             * @see #getSofZmanShmaMGA()
1144             */
1145            public Date getSofZmanTfilaMGA72Minutes() {
1146                    return getSofZmanTfilaMGA();
1147            }
1148    
1149            /**
1150             * This method returns the latest <em>zman tfila</em> (time to the morning
1151             * prayers) in the opinion of the <em>MG"A</em> based on <em>alos</em>
1152             * being {@link #getAlos72Zmanis() 72} minutes <em>zmaniyos</em> before
1153             * {@link #getSunrise() sunrise}. This time is 4
1154             * <em>{@link #getShaahZmanis72MinutesZmanis() shaos zmaniyos}</em> (solar
1155             * hours) after {@link #getAlos72Zmanis() dawn} based on the opinion of the
1156             * <em>MG"A</em> that the day is calculated from a
1157             * {@link #getAlos72Zmanis() dawn} of 72 minutes <em>zmaniyos</em> before
1158             * sunrise to {@link #getTzais72Zmanis() nightfall} of 72 minutes
1159             * <em>zmaniyos</em> after sunset. This returns the time of 4 *
1160             * {@link #getShaahZmanis72MinutesZmanis()} after
1161             * {@link #getAlos72Zmanis() dawn}.
1162             * 
1163             * @return the <code>Date</code> of the latest zman shema.
1164             * @see #getShaahZmanis72MinutesZmanis()
1165             * @see #getAlos72Zmanis()
1166             */
1167            public Date getSofZmanTfilaMGA72MinutesZmanis() {
1168                    return getTimeOffset(getAlos72Zmanis(),
1169                                    getShaahZmanis72MinutesZmanis() * 4);
1170            }
1171    
1172            /**
1173             * This method returns the latest <em>zman tfila</em> (time to say the
1174             * morning prayers) in the opinion of the <em>MG"A</em> based on
1175             * <em>alos</em> being {@link #getAlos90() 90} minutes before
1176             * {@link #getSunrise() sunrise}. This time is 4
1177             * <em>{@link #getShaahZmanis90Minutes() shaos zmaniyos}</em> (solar
1178             * hours) after {@link #getAlos90() dawn} based on the opinion of the
1179             * <em>MG"A</em> that the day is calculated from a
1180             * {@link #getAlos90() dawn} of 90 minutes before sunrise to
1181             * {@link #getTzais90() nightfall} of 90 minutes after sunset. This returns
1182             * the time of 4 * {@link #getShaahZmanis90Minutes()} after
1183             * {@link #getAlos90() dawn}.
1184             * 
1185             * @return the <code>Date</code> of the latest zman tfila.
1186             * @see #getShaahZmanis90Minutes()
1187             * @see #getAlos90()
1188             */
1189            public Date getSofZmanTfilaMGA90Minutes() {
1190                    return getTimeOffset(getAlos90(), getShaahZmanis90Minutes() * 4);
1191            }
1192    
1193            /**
1194             * This method returns the latest <em>zman tfila</em> (time to the morning
1195             * prayers) in the opinion of the <em>MG"A</em> based on <em>alos</em>
1196             * being {@link #getAlos90Zmanis() 90} minutes <em>zmaniyos</em> before
1197             * {@link #getSunrise() sunrise}. This time is 4
1198             * <em>{@link #getShaahZmanis90MinutesZmanis() shaos zmaniyos}</em> (solar
1199             * hours) after {@link #getAlos90Zmanis() dawn} based on the opinion of the
1200             * <em>MG"A</em> that the day is calculated from a
1201             * {@link #getAlos90Zmanis() dawn} of 90 minutes <em>zmaniyos</em> before
1202             * sunrise to {@link #getTzais90Zmanis() nightfall} of 90 minutes
1203             * <em>zmaniyos</em> after sunset. This returns the time of 4 *
1204             * {@link #getShaahZmanis90MinutesZmanis()} after
1205             * {@link #getAlos90Zmanis() dawn}.
1206             * 
1207             * @return the <code>Date</code> of the latest zman shema.
1208             * @see #getShaahZmanis90MinutesZmanis()
1209             * @see #getAlos90Zmanis()
1210             */
1211            public Date getSofZmanTfilaMGA90MinutesZmanis() {
1212                    return getTimeOffset(getAlos90Zmanis(),
1213                                    getShaahZmanis90MinutesZmanis() * 4);
1214            }
1215    
1216            /**
1217             * This method returns the latest <em>zman tfila</em> (time to say the
1218             * morning prayers) in the opinion of the <em>MG"A</em> based on
1219             * <em>alos</em> being {@link #getAlos96() 96} minutes before
1220             * {@link #getSunrise() sunrise}. This time is 4
1221             * <em>{@link #getShaahZmanis96Minutes() shaos zmaniyos}</em> (solar
1222             * hours) after {@link #getAlos96() dawn} based on the opinion of the
1223             * <em>MG"A</em> that the day is calculated from a
1224             * {@link #getAlos96() dawn} of 96 minutes before sunrise to
1225             * {@link #getTzais96() nightfall} of 96 minutes after sunset. This returns
1226             * the time of 4 * {@link #getShaahZmanis96Minutes()} after
1227             * {@link #getAlos96() dawn}.
1228             * 
1229             * @return the <code>Date</code> of the latest zman tfila.
1230             * @see #getShaahZmanis96Minutes()
1231             * @see #getAlos96()
1232             */
1233            public Date getSofZmanTfilaMGA96Minutes() {
1234                    return getTimeOffset(getAlos96(), getShaahZmanis96Minutes() * 4);
1235            }
1236    
1237            /**
1238             * This method returns the latest <em>zman tfila</em> (time to the morning
1239             * prayers) in the opinion of the <em>MG"A</em> based on <em>alos</em>
1240             * being {@link #getAlos96Zmanis() 96} minutes <em>zmaniyos</em> before
1241             * {@link #getSunrise() sunrise}. This time is 4
1242             * <em>{@link #getShaahZmanis96MinutesZmanis() shaos zmaniyos}</em> (solar
1243             * hours) after {@link #getAlos96Zmanis() dawn} based on the opinion of the
1244             * <em>MG"A</em> that the day is calculated from a
1245             * {@link #getAlos96Zmanis() dawn} of 96 minutes <em>zmaniyos</em> before
1246             * sunrise to {@link #getTzais96Zmanis() nightfall} of 96 minutes
1247             * <em>zmaniyos</em> after sunset. This returns the time of 4 *
1248             * {@link #getShaahZmanis96MinutesZmanis()} after
1249             * {@link #getAlos96Zmanis() dawn}.
1250             * 
1251             * @return the <code>Date</code> of the latest zman shema.
1252             * @see #getShaahZmanis90MinutesZmanis()
1253             * @see #getAlos90Zmanis()
1254             */
1255            public Date getSofZmanTfilaMGA96MinutesZmanis() {
1256                    return getTimeOffset(getAlos96Zmanis(),
1257                                    getShaahZmanis96MinutesZmanis() * 4);
1258            }
1259    
1260            /**
1261             * This method returns the latest <em>zman tfila</em> (time to say the
1262             * morning prayers) in the opinion of the <em>MG"A</em> based on
1263             * <em>alos</em> being {@link #getAlos120() 120} minutes before
1264             * {@link #getSunrise() sunrise}. This time is 4
1265             * <em>{@link #getShaahZmanis120Minutes() shaos zmaniyos}</em> (solar
1266             * hours) after {@link #getAlos120() dawn} based on the opinion of the
1267             * <em>MG"A</em> that the day is calculated from a
1268             * {@link #getAlos120() dawn} of 120 minutes before sunrise to
1269             * {@link #getTzais120() nightfall} of 120 minutes after sunset. This
1270             * returns the time of 4 *{@link #getShaahZmanis120Minutes()} after
1271             * {@link #getAlos120() dawn}.
1272             * 
1273             * @return the <code>Date</code> of the latest zman shema.
1274             * @see #getShaahZmanis120Minutes()
1275             * @see #getAlos120()
1276             */
1277            public Date getSofZmanTfilaMGA120Minutes() {
1278                    return getTimeOffset(getAlos120(), getShaahZmanis120Minutes() * 4);
1279            }
1280    
1281            /**
1282             * This method returns the latest <em>zman tfila</em> (time to say the
1283             * morning prayers) calculated as 2 hours befor
1284             * {@link ZmanimCalendar#getChatzos()}. This is based on the opinions that
1285             * calculate <em>sof zman krias shema</em> as
1286             * {@link #getSofZmanShma3HoursBeforeChatzos()}. This returns the time of 2
1287             * hours before {@link ZmanimCalendar#getChatzos()}.
1288             * 
1289             * @return the <code>Date</code> of the latest zman shema.
1290             * @see ZmanimCalendar#getChatzos()
1291             * @see #getSofZmanShma3HoursBeforeChatzos()
1292             */
1293            public Date getSofZmanTfila2HoursBeforeChatzos() {
1294                    return getTimeOffset(getChatzos(), -120 * MINUTE_MILLIS);
1295            }
1296    
1297            /**
1298             * This method returns mincha gedola calculated as 30 minutes after
1299             * <em>{@link #getChatzos() chatzos}</em> and not 1/2 of a
1300             * <em>{@link #getShaahZmanisGra() shaah zmanis}</em> after
1301             * <em>{@link #getChatzos() chatzos}</em> as calculated by
1302             * {@link #getMinchaGedola}. Some use this time to delay the start of
1303             * mincha in the winter when 1/2 of a
1304             * <em>{@link #getShaahZmanisGra() shaah zmanis}</em> is less than 30
1305             * minutes. See {@link #getMinchaGedolaGreaterThan30()}for a conveniance
1306             * method that returns the later of the 2 calculations. One should not use
1307             * this time to start <em>mincha</em> before the standard
1308             * <em>{@link #getMinchaGedola() mincha gedola}</em>. See
1309             * <em>Shulchan Aruch
1310             * Orach Chayim Siman Raish Lamed Gimel seif alef</em>
1311             * and the <em>Shaar Hatziyon seif katan ches</em>.
1312             * 
1313             * @return the <code>Date</code> of 30 mintes after <em>chatzos</em>.
1314             * @see #getMinchaGedola()
1315             * @see #getMinchaGedolaGreaterThan30()
1316             */
1317            public Date getMinchaGedola30Minutes() {
1318                    return getTimeOffset(getChatzos(), MINUTE_MILLIS * 30);
1319            }
1320    
1321            /**
1322             * This method returns the time of <em>mincha gedola</em> according to the
1323             * Magen Avraham with the day starting 72 minutes before sunrise and ending
1324             * 72 minutes after sunset. This is the earliest time to pray
1325             * <em>mincha</em>. For more information on this see the documentation on
1326             * <em>{@link #getMinchaGedola() mincha gedola}</em>. This is calculated
1327             * as 6.5 {@link #getTemporalHour() solar hours} after alos. The calculation
1328             * used is 6.5 * {@link #getShaahZmanis72Minutes()} after
1329             * {@link #getAlos72() alos}.
1330             * 
1331             * @see #getAlos72()()
1332             * @see #getMinchaGedola()
1333             * @see #getMinchaKetana()
1334             * @see ZmanimCalendar#getMinchaGedola()
1335             * @return the <code>Date</code> of the time of mincha gedola.
1336             */
1337            public Date getMinchaGedola72Minutes() {
1338                    return getTimeOffset(getAlos72(), getShaahZmanis72Minutes() * 6.5);
1339            }
1340    
1341            /**
1342             * This method returns the time of <em>mincha gedola</em> according to the
1343             * Magen Avraham with the day starting and ending 16.1&deg; below the
1344             * horizon. This is the earliest time to pray <em>mincha</em>. For more
1345             * information on this see the documentation on
1346             * <em>{@link #getMinchaGedola() mincha gedola}</em>. This is calculated
1347             * as 6.5 {@link #getTemporalHour() solar hours} after alos. The calculation
1348             * used is 6.5 * {@link #getShaahZmanis16Point1Degrees()} after
1349             * {@link #getAlos16Point1Degrees() alos}.
1350             * 
1351             * @see #getShaahZmanis16Point1Degrees()
1352             * @see #getMinchaGedola()
1353             * @see #getMinchaKetana()
1354             * @return the <code>Date</code> of the time of mincha gedola.
1355             */
1356            public Date getMinchaGedola16Point1Degrees() {
1357                    return getTimeOffset(getAlos16Point1Degrees(),
1358                                    getShaahZmanis16Point1Degrees() * 6.5);
1359            }
1360    
1361            /**
1362             * This is a conveniance methd that returns the later of
1363             * {@link #getMinchaGedola()}and {@link #getMinchaGedola30Minutes()}. In
1364             * the winter when a <em>{@link #getShaahZmanisGra() shaah zmanis}</em> is
1365             * less than 30 minutes {@link #getMinchaGedola30Minutes()}will be
1366             * returned, otherwise {@link #getMinchaGedola()} will be returned.
1367             * 
1368             * @return the <code>Date</code> of the later of
1369             *         {@link #getMinchaGedola()}and
1370             *         {@link #getMinchaGedola30Minutes()}
1371             */
1372            public Date getMinchaGedolaGreaterThan30() {
1373                    if (getMinchaGedola30Minutes() == null || getMinchaGedola() == null) {
1374                            return null;
1375                    } else {
1376                            return getMinchaGedola30Minutes().compareTo(getMinchaGedola()) > 0 ? getMinchaGedola30Minutes()
1377                                            : getMinchaGedola();
1378                    }
1379            }
1380    
1381            /**
1382             * This method returns the time of <em>mincha ketana</em> according to the
1383             * Magen Avraham with the day starting and ending 16.1&deg; below the
1384             * horizon. This is the perfered earliest time to pray <em>mincha</em> in
1385             * the opinion of the Ramba"m and others. For more information on this see
1386             * the documentation on <em>{@link #getMinchaGedola() mincha gedola}</em>.
1387             * This is calculated as 9.5 {@link #getTemporalHour() solar hours} after
1388             * alos. The calculation used is 9.5 *
1389             * {@link #getShaahZmanis16Point1Degrees()} after
1390             * {@link #getAlos16Point1Degrees() alos}.
1391             * 
1392             * @see #getShaahZmanis16Point1Degrees()
1393             * @see #getMinchaGedola()
1394             * @see #getMinchaKetana()
1395             * @return the <code>Date</code> of the time of mincha ketana.
1396             */
1397            public Date getMinchaKetana16Point1Degrees() {
1398                    return getTimeOffset(getAlos16Point1Degrees(),
1399                                    getShaahZmanis16Point1Degrees() * 9.5);
1400            }
1401    
1402            /**
1403             * This method returns the time of <em>mincha ketana</em> according to the
1404             * Magen Avraham with the day starting 72 minutes before sunrise and ending
1405             * 72 minutes after sunset. This is the perfered earliest time to pray
1406             * <em>mincha</em> in the opinion of the Ramba"m and others. For more
1407             * information on this see the documentation on
1408             * <em>{@link #getMinchaGedola() mincha gedola}</em>. This is calculated
1409             * as 9.5 {@link #getShaahZmanis72Minutes()} after alos. The calculation
1410             * used is 9.5 * {@link #getShaahZmanis72Minutes()} after
1411             * {@link #getAlos72() alos}.
1412             * 
1413             * @see #getShaahZmanis16Point1Degrees()
1414             * @see #getMinchaGedola()
1415             * @see #getMinchaKetana()
1416             * @return the <code>Date</code> of the time of mincha ketana.
1417             */
1418            public Date getMinchaKetana72Minutes() {
1419                    return getTimeOffset(getAlos72(), getShaahZmanis72Minutes() * 9.5);
1420            }
1421    
1422            /**
1423             * This method returns the time of <em>plag hamincha</em>. This is
1424             * calculated as 10.75 hours after {@link #getAlos72() dawn}. The formula
1425             * used is:<br/> 10.75 *{@link #getShaahZmanis72Minutes()} after
1426             * {@link #getAlos72()}.
1427             * 
1428             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
1429             */
1430            public Date getPlagHamincha60Minutes() {
1431                    return getTimeOffset(getAlos60(), getShaahZmanis60Minutes() * 10.75);
1432            }
1433    
1434            /**
1435             * This method returns the time of <em>plag hamincha</em>. This is
1436             * calculated as 10.75 hours after {@link #getAlos72() dawn}. The formula
1437             * used is:<br/> 10.75 *{@link #getShaahZmanis72Minutes()} after
1438             * {@link #getAlos72()}.
1439             * 
1440             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
1441             */
1442            public Date getPlagHamincha72Minutes() {
1443                    return getTimeOffset(getAlos72(), getShaahZmanis72Minutes() * 10.75);
1444            }
1445    
1446            /**
1447             * This method returns the time of <em>plag hamincha</em>. This is
1448             * calculated as 10.75 hours after {@link #getAlos90() dawn}. The formula
1449             * used is:<br/> 10.75 *{@link #getShaahZmanis90Minutes()} after
1450             * {@link #getAlos90()}.
1451             * 
1452             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
1453             */
1454            public Date getPlagHamincha90Minutes() {
1455                    return getTimeOffset(getAlos90(), getShaahZmanis90Minutes() * 10.75);
1456            }
1457    
1458            /**
1459             * This method returns the time of <em>plag hamincha</em>. This is
1460             * calculated as 10.75 hours after {@link #getAlos96() dawn}. The formula
1461             * used is:<br/> 10.75 *{@link #getShaahZmanis96Minutes()} after
1462             * {@link #getAlos96()}.
1463             * 
1464             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
1465             */
1466            public Date getPlagHamincha96Minutes() {
1467                    return getTimeOffset(getAlos96(), getShaahZmanis96Minutes() * 10.75);
1468            }
1469    
1470            /**
1471             * This method returns the time of <em>plag hamincha</em>. This is
1472             * calculated as 10.75 hours after {@link #getAlos96Zmanis() dawn}. The
1473             * formula used is:<br/> 10.75 * {@link #getShaahZmanis96MinutesZmanis()}
1474             * after {@link #getAlos96Zmanis() dawn}.
1475             * 
1476             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
1477             */
1478            public Date getPlagHamincha96MinutesZmanis() {
1479                    return getTimeOffset(getAlos96Zmanis(),
1480                                    getShaahZmanis96MinutesZmanis() * 10.75);
1481            }
1482    
1483            /**
1484             * This method returns the time of <em>plag hamincha</em>. This is
1485             * calculated as 10.75 hours after {@link #getAlos90Zmanis() dawn}. The
1486             * formula used is:<br/> 10.75 * {@link #getShaahZmanis90MinutesZmanis()}
1487             * after {@link #getAlos90Zmanis() dawn}.
1488             * 
1489             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
1490             */
1491            public Date getPlagHamincha90MinutesZmanis() {
1492                    return getTimeOffset(getAlos90Zmanis(),
1493                                    getShaahZmanis90MinutesZmanis() * 10.75);
1494            }
1495    
1496            /**
1497             * This method returns the time of <em>plag hamincha</em>. This is
1498             * calculated as 10.75 hours after {@link #getAlos72Zmanis() dawn}. The
1499             * formula used is:<br/> 10.75 * {@link #getShaahZmanis72MinutesZmanis()}
1500             * after {@link #getAlos72Zmanis() dawn}.
1501             * 
1502             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
1503             */
1504            public Date getPlagHamincha72MinutesZmanis() {
1505                    return getTimeOffset(getAlos72Zmanis(),
1506                                    getShaahZmanis72MinutesZmanis() * 10.75);
1507            }
1508    
1509            /**
1510             * This method returns the time of <em>plag hamincha</em> based on the
1511             * opinion that the day starts at
1512             * <em>{@link #getAlos16Point1Degrees() alos 16.1&deg;}</em> and ends at
1513             * <em>{@link #getTzais16Point1Degrees() tzais 16.1&deg;}</em>. This is
1514             * calculated as 10.75 hours <em>zmaniyos</em> after
1515             * {@link #getAlos16Point1Degrees() dawn}. The formula is<br/>10.75 *
1516             * {@link #getShaahZmanis16Point1Degrees()} after
1517             * {@link #getAlos16Point1Degrees()}.
1518             * 
1519             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
1520             */
1521            public Date getPlagHamincha16Point1Degrees() {
1522                    return getTimeOffset(getAlos16Point1Degrees(),
1523                                    getShaahZmanis16Point1Degrees() * 10.75);
1524            }
1525    
1526            /**
1527             * This method returns the time of <em>plag hamincha</em> based on the
1528             * opinion that the day starts at
1529             * <em>{@link #getAlos19Point8Degrees() alos 19.8&deg;}</em> and ends at
1530             * <em>{@link #getTzais19Point8Degrees() tzais 19.8&deg;}</em>. This is
1531             * calculated as 10.75 hours <em>zmaniyos</em> after
1532             * {@link #getAlos19Point8Degrees() dawn}. The formula is<br/>10.75 *
1533             * {@link #getShaahZmanis19Point8Degrees()} after
1534             * {@link #getAlos19Point8Degrees()}.
1535             * 
1536             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
1537             */
1538            public Date getPlagHamincha19Point8Degrees() {
1539                    return getTimeOffset(getAlos19Point8Degrees(),
1540                                    getShaahZmanis19Point8Degrees() * 10.75);
1541            }
1542    
1543            /**
1544             * This method returns the time of <em>plag hamincha</em> based on the
1545             * opinion that the day starts at
1546             * <em>{@link #getAlos26Degrees() alos 26&deg;}</em> and ends at
1547             * <em>{@link #getTzais26Degrees() tzais 26&deg;}</em>. This is
1548             * calculated as 10.75 hours <em>zmaniyos</em> after
1549             * {@link #getAlos26Degrees() dawn}. The formula is<br/>10.75 *
1550             * {@link #getShaahZmanis26Degrees()} after {@link #getAlos26Degrees()}.
1551             * 
1552             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
1553             */
1554            public Date getPlagHamincha26Degrees() {
1555                    return getTimeOffset(getAlos26Degrees(),
1556                                    getShaahZmanis26Degrees() * 10.75);
1557            }
1558    
1559            /**
1560             * This method returns the time of <em>plag hamincha</em> based on the
1561             * opinion that the day starts at
1562             * <em>{@link #getAlos18Degrees() alos 18&deg;}</em> and ends at
1563             * <em>{@link #getTzais18Degrees() tzais 18&deg;}</em>. This is
1564             * calculated as 10.75 hours <em>zmaniyos</em> after
1565             * {@link #getAlos18Degrees() dawn}. The formula is<br/>10.75 *
1566             * {@link #getShaahZmanis18Degrees()} after {@link #getAlos18Degrees()}.
1567             * 
1568             * @return the <code>Date</code> of the time of <em>plag hamincha</em>.
1569             */
1570            public Date getPlagHamincha18Degrees() {
1571                    return getTimeOffset(getAlos18Degrees(),
1572                                    getShaahZmanis18Degrees() * 10.75);
1573            }
1574    
1575            /**
1576             * This method returns the time of <em>plag hamincha</em> based on the
1577             * opinion that the day starts at
1578             * <em>{@link #getAlos16Point1Degrees() alos 16.1&deg;}</em> and ends at
1579             * {@link #getSunset() sunset}. 10.75 shaos zmaniyos are calculated based
1580             * on this day and added to {@link #getAlos16Point1Degrees() alos} to reach
1581             * this time. This time is 10.75 <em>shaos zmaniyos</em> (temporal hours)
1582             * after {@link #getAlos16Point1Degrees() dawn} based on the opinion that
1583             * the day is calculated from a {@link #getAlos16Point1Degrees() dawn} of
1584             * 16.1 degrees before sunrise to {@link #getSunset() sunset}. This returns
1585             * the time of 10.75 * the calculated <em>shaah zmanis</em> after
1586             * {@link #getAlos16Point1Degrees() dawn}.
1587             * 
1588             * @return the <code>Date</code> of the plag.
1589             * @see #getAlos16Point1Degrees()
1590             * @see #getSunset()
1591             */
1592            public Date getPlagAlosToSunset() {
1593                    long shaahZmanis = getTemporalHour(getAlos16Point1Degrees(),
1594                                    getSunset());
1595                    return getTimeOffset(getAlos16Point1Degrees(), shaahZmanis * 10.75);
1596            }
1597    
1598            /**
1599             * This method returns the time of <em>plag hamincha</em> based on the
1600             * opinion that the day starts at
1601             * <em>{@link #getAlos16Point1Degrees() alos 16.1&deg;}</em> and ends at
1602             * {@link #getTzaisGeonim7Point083Degrees() tzais}. 10.75 shaos zmaniyos
1603             * are calculated based on this day and added to
1604             * {@link #getAlos16Point1Degrees() alos} to reach this time. This time is
1605             * 10.75 <em>shaos zmaniyos</em> (temporal hours) after
1606             * {@link #getAlos16Point1Degrees() dawn} based on the opinion that the day
1607             * is calculated from a {@link #getAlos16Point1Degrees() dawn} of 16.1
1608             * degrees before sunrise to {@link #getTzaisGeonim7Point083Degrees() tzais}.
1609             * This returns the time of 10.75 * the calculated <em>shaah zmanis</em>
1610             * after {@link #getAlos16Point1Degrees() dawn}.
1611             * 
1612             * @return the <code>Date</code> of the plag.
1613             * @see #getAlos16Point1Degrees()
1614             * @see #getTzaisGeonim7Point083Degrees()
1615             */
1616            public Date getPlagAlos16Point1ToTzaisGeonim7Point083Degrees() {
1617                    long shaahZmanis = getTemporalHour(getAlos16Point1Degrees(),
1618                                    getTzaisGeonim7Point083Degrees());
1619                    return getTimeOffset(getAlos16Point1Degrees(), shaahZmanis * 10.75);
1620            }
1621    
1622            /**
1623             * This method returns Bain Hashmashos of Rabainu Tam calculated as the time
1624             * the sun is 13&deg; below {@link #GEOMETRIC_ZENITH  geometric zenith}
1625             * (90&deg;). <br/><br/><b>FIXME:</b> As per Yisroel Vehazmanim Vol III
1626             * page 1028 No 50, the 13&deg; is slightly inaccurate. He lists it as a
1627             * drop less than 13&deg;. Calculations show that is seems to be
1628             * 13.2477&deg; below the horizon at that time. This makes a difference of 1
1629             * minute and 10 seconds in Jerusalem in the Equinox, and 1 minute 29
1630             * seconds in the solstice. for NY in the solstice, the difference is 1
1631             * minute 56 seconds.
1632             * 
1633             * @return the <code>Date</code> of the sun being 13&deg; below
1634             *         {@link #GEOMETRIC_ZENITH  geometric zenith} (90&deg;).
1635             * @see #ZENITH_13_DEGREES
1636             * 
1637             */
1638            public Date getBainHasmashosRT13Degrees() {
1639                    return getSunsetOffsetByDegrees(ZENITH_13_DEGREES);
1640            }
1641    
1642            public Date getBainHasmashosRT58Point5Minutes() {
1643                    return getTimeOffset(getSeaLevelSunset(), 58.5 * MINUTE_MILLIS);
1644            }
1645    
1646            public Date getBainHasmashosRT13Point5MinutesBefore7Point083Degrees() {
1647                    return getTimeOffset(getSunsetOffsetByDegrees(ZENITH_7_POINT_083),
1648                                    -13.5 * MINUTE_MILLIS);
1649            }
1650    
1651            public Date getBainHasmashosRT2Stars() {
1652                    Date alos19Point8 = getAlos19Point8Degrees();
1653                    Date sunrise = getSunrise();
1654                    if (alos19Point8 == null || sunrise == null) {
1655                            return null;
1656                    }
1657                    return getTimeOffset(getSunset(), (sunrise.getTime() - alos19Point8
1658                                    .getTime())
1659                                    * (5 / 18d));
1660            }
1661    
1662            /**
1663             * This method returns the <em>tzais</em> (nightfall) based on the opinion
1664             * of the <em>Geonim</em> calculated at the sun's position at
1665             * {@link #ZENITH_5_POINT_95 5.95&deg;} below the western horizon.
1666             * 
1667             * @return the <code>Date</code> representing the time when the sun is
1668             *         5.95&deg; below sea level.
1669             * @see #ZENITH_5_POINT_95
1670             */
1671            // public Date getTzaisGeonim3Point7Degrees() {
1672            // return getSunsetOffsetByDegrees(ZENITH_3_POINT_7);
1673            // }
1674            /**
1675             * This method returns the <em>tzais</em> (nightfall) based on the opinion
1676             * of the <em>Geonim</em> calculated at the sun's position at
1677             * {@link #ZENITH_5_POINT_95 5.95&deg;} below the western horizon.
1678             * 
1679             * @return the <code>Date</code> representing the time when the sun is
1680             *         5.95&deg; below sea level.
1681             * @see #ZENITH_5_POINT_95
1682             */
1683            public Date getTzaisGeonim5Point95Degrees() {
1684                    return getSunsetOffsetByDegrees(ZENITH_5_POINT_95);
1685            }
1686    
1687            /**
1688             * This method returns the <em>tzais</em> (nightfall) based on the opinion
1689             * of the <em>Geonim</em> calculated at the sun's position at
1690             * {@link #ZENITH_7_POINT_083 7.083&deg;} below the western horizon.
1691             * 
1692             * @return the <code>Date</code> representing the time when the sun is
1693             *         7.083&deg; below sea level.
1694             * @see #ZENITH_7_POINT_083
1695             */
1696            public Date getTzaisGeonim7Point083Degrees() {
1697                    return getSunsetOffsetByDegrees(ZENITH_7_POINT_083);
1698            }
1699    
1700            /**
1701             * This method returns the <em>tzais</em> (nightfall) based on the opinion
1702             * of the <em>Geonim</em> calculated at the sun's position at
1703             * {@link #ZENITH_8_POINT_5 8.5&deg;} below the western horizon.
1704             * 
1705             * @return the <code>Date</code> representing the time when the sun is
1706             *         8.5&deg; below sea level.
1707             * @see #ZENITH_8_POINT_5
1708             */
1709            public Date getTzaisGeonim8Point5Degrees() {
1710                    return getSunsetOffsetByDegrees(ZENITH_8_POINT_5);
1711            }
1712    
1713            /**
1714             * This method returns the <em>tzais</em> (nightfall) based on the opinion
1715             * of the Chavas Yair and Divray Malkiel that the time to walk the distance
1716             * of a Mil is 15 minutes for a total of 60 minutes for 4 mil after sea
1717             * level sunset.
1718             * 
1719             * @return the <code>Date</code> representing 60 minutes after sea level
1720             *         sunset.
1721             * @see #getAlos60()
1722             */
1723            public Date getTzais60() {
1724                    return getTimeOffset(getSeaLevelSunset(), 60 * MINUTE_MILLIS);
1725            }
1726    
1727            /**
1728             * This method returns tzais usually calculated as 40 minutes after sunset.
1729             * Please note that Chacham Yosef Harari-Raful of Yeshivat Ateret Torah who
1730             * uses this time, does so only for calculating various other zmanai hayom
1731             * such as Sof Zman Krias Shema and Plag Hamincha. His calendars do not
1732             * publish a zman for Tzais. It should also be noted that Chacham
1733             * Harari-Raful provided a 25 minute zman for Israel. This API uses 40
1734             * minutes year round in any place on the globe by default. This offset can
1735             * be changed by calling {@link #setAteretTorahSunsetOffset(double)}.
1736             * 
1737             * @return the <code>Date</code> representing 40 minutes after sea level
1738             *         sunset
1739             * @see #getAteretTorahSunsetOffset()
1740             * @see #setAteretTorahSunsetOffset(double)
1741             */
1742            public Date getTzaisAteretTorah() {
1743                    return getTimeOffset(getSeaLevelSunset(), getAteretTorahSunsetOffset()
1744                                    * MINUTE_MILLIS);
1745            }
1746    
1747            /**
1748             * Returns the offset in minutes after sunset used to calculate
1749             * <em>tzais</em> for the Ateret Torah zmanim. The defaullt value is 40
1750             * minutes.
1751             * 
1752             * @return the number of minutes after sunset for Tzais.
1753             * @see #setAteretTorahSunsetOffset(double)
1754             */
1755            public double getAteretTorahSunsetOffset() {
1756                    return ateretTorahSunsetOffset;
1757            }
1758    
1759            /**
1760             * Allows setting the offset in minutes after sunset for the Ateret Torah
1761             * zmanim. The default if unset is 40 minutes. Chacham Yosef Harari-Raful of
1762             * Yeshivat Ateret Torah uses 40 minutes globally with the exception of
1763             * Israel where a 25 minute offset is used. This 25 minute (or any other)
1764             * offset can be overridden by this methd. This offset impacts all Ateret
1765             * Torah methods.
1766             * 
1767             * @param ateretTorahSunsetOffset
1768             *            the number of minutes after sunset to use as an offset for the
1769             *            Ateret Torah <em>tzais</em>
1770             * @see #getAteretTorahSunsetOffset()
1771             */
1772            public void setAteretTorahSunsetOffset(double ateretTorahSunsetOffset) {
1773                    this.ateretTorahSunsetOffset = ateretTorahSunsetOffset;
1774            }
1775    
1776            /**
1777             * This method returns the latest <em>zman krias shema</em> (time to say
1778             * Shema in the morning) based on the calculation of Chacham Yosef
1779             * Harari-Raful of Yeshivat Ateret Torah, that the day starts
1780             * {@link #getAlos72Zmanis() 1/10th of the day} before sunrise and is
1781             * usually calculated as ending
1782             * {@link #getTzaisAteretTorah() 40 minutes after sunset}.
1783             * <em>shaos zmaniyos</em> are calculated based on this day and added to
1784             * {@link #getAlos72Zmanis() alos} to reach this time. This time is 3
1785             * <em> {@link #getShaahZmanisAteretTorah() shaos zmaniyos}</em> (temporal
1786             * hours) after {@link #getAlos72Zmanis() alos 72 zmaniyos}.<br />
1787             * <b>Note: </b> Based on this calculation <em>chatzos</em> will not be at
1788             * midday.
1789             * 
1790             * @return the <code>Date</code> of the latest zman shema based on this
1791             *         calculation.
1792             * @see #getAlos72Zmanis()
1793             * @see #getTzaisAteretTorah()
1794             * @see #getAteretTorahSunsetOffset()
1795             * @see #setAteretTorahSunsetOffset(double)
1796             * @see #getShaahZmanisAteretTorah()
1797             */
1798            public Date getSofZmanShmaAteretTorah() {
1799                    return getTimeOffset(getAlos72Zmanis(), getShaahZmanisAteretTorah() * 3);
1800            }
1801    
1802            /**
1803             * This method returns the latest <em>zman tfila</em> (time to say the
1804             * morning prayers) based on the calculation of Chacham Yosef Harari-Raful
1805             * of Yeshivat Ateret Torah, that the day starts
1806             * {@link #getAlos72Zmanis() 1/10th of the day} before sunrise and and is
1807             * usually calculated as ending
1808             * {@link #getTzaisAteretTorah() 40 minutes after sunset}.
1809             * <em>shaos zmaniyos</em> are calculated based on this day and added to
1810             * {@link #getAlos72Zmanis() alos} to reach this time. This time is 4
1811             * <em>{@link #getShaahZmanisAteretTorah() shaos zmaniyos}</em> (temporal
1812             * hours) after {@link #getAlos72Zmanis() alos 72 zmaniyos}.<br />
1813             * <b>Note: </b> Based on this calculation <em>chatzos</em> will not be at
1814             * midday.
1815             * 
1816             * @return the <code>Date</code> of the latest zman shema based on this
1817             *         calculation.
1818             * @see #getAlos72Zmanis()
1819             * @see #getTzaisAteretTorah()
1820             * @see #getShaahZmanisAteretTorah()
1821             * @see #setAteretTorahSunsetOffset(double)
1822             */
1823            public Date getSofZmanTfilahAteretTorah() {
1824                    return getTimeOffset(getAlos72Zmanis(), getShaahZmanisAteretTorah() * 4);
1825            }
1826    
1827            /**
1828             * This method returns the time of <em>mincha gedola</em> based on the
1829             * calculation of Chacham Yosef Harari-Raful of Yeshivat Ateret Torah, that
1830             * the day starts {@link #getAlos72Zmanis() 1/10th of the day} before
1831             * sunrise and and is usually calculated as ending
1832             * {@link #getTzaisAteretTorah() 40 minutes after sunset}. This is the
1833             * perfered earliest time to pray <em>mincha</em> in the opinion of the
1834             * Ramba"m and others. For more information on this see the documentation on
1835             * <em>{@link #getMinchaGedola() mincha gedola}</em>. This is calculated
1836             * as 6.5 {@link #getShaahZmanisAteretTorah() solar hours} after alos. The
1837             * calculation used is 6.5 * {@link #getShaahZmanisAteretTorah()} after
1838             * {@link #getAlos72Zmanis() alos}.
1839             * 
1840             * @see #getAlos72Zmanis()
1841             * @see #getTzaisAteretTorah()
1842             * @see #getShaahZmanisAteretTorah()
1843             * @see #getMinchaGedola()
1844             * @see #getMinchaKetanaAteretTorah()
1845             * @see ZmanimCalendar#getMinchaGedola()
1846             * @return the <code>Date</code> of the time of mincha gedola.
1847             */
1848            public Date getMinchaGedolaAteretTorah() {
1849                    return getTimeOffset(getAlos72Zmanis(),
1850                                    getShaahZmanisAteretTorah() * 6.5);
1851            }
1852    
1853            /**
1854             * This method returns the time of <em>mincha ketana</em> based on the
1855             * calculation of Chacham Yosef Harari-Raful of Yeshivat Ateret Torah, that
1856             * the day starts {@link #getAlos72Zmanis() 1/10th of the day} before
1857             * sunrise and and is usually calculated as ending
1858             * {@link #getTzaisAteretTorah() 40 minutes after sunset}. This is the
1859             * perfered earliest time to pray <em>mincha</em> in the opinion of the
1860             * Ramba"m and others. For more information on this see the documentation on
1861             * <em>{@link #getMinchaGedola() mincha gedola}</em>. This is calculated
1862             * as 9.5 {@link #getShaahZmanisAteretTorah() solar hours} after
1863             * {@link #getAlos72Zmanis() alos}. The calculation used is 9.5 *
1864             * {@link #getShaahZmanisAteretTorah()} after
1865             * {@link #getAlos72Zmanis() alos}.
1866             * 
1867             * @see #getAlos72Zmanis()
1868             * @see #getTzaisAteretTorah()
1869             * @see #getShaahZmanisAteretTorah()
1870             * @see #getMinchaGedola()
1871             * @see #getMinchaKetana()
1872             * @return the <code>Date</code> of the time of mincha ketana.
1873             */
1874            public Date getMinchaKetanaAteretTorah() {
1875                    return getTimeOffset(getAlos72Zmanis(),
1876                                    getShaahZmanisAteretTorah() * 9.5);
1877            }
1878    
1879            /**
1880             * This method returns the time of <em>plag hamincha</em> based on the
1881             * calculation of Chacham Yosef Harari-Raful of Yeshivat Ateret Torah, that
1882             * the day starts {@link #getAlos72Zmanis() 1/10th of the day} before
1883             * sunrise and and is usually calculated as ending
1884             * {@link #getTzaisAteretTorah() 40 minutes after sunset}.
1885             * <em>shaos zmaniyos</em> are calculated based on this day and added to
1886             * {@link #getAlos72Zmanis() alos} to reach this time. This time is 10.75
1887             * <em>{@link #getShaahZmanisAteretTorah() shaos zmaniyos}</em> (temporal
1888             * hours) after {@link #getAlos72Zmanis() dawn}.
1889             * 
1890             * @return the <code>Date</code> of the plag.
1891             * @see #getAlos72Zmanis()
1892             * @see #getTzaisAteretTorah()
1893             * @see #getShaahZmanisAteretTorah()
1894             */
1895            public Date getPlagHaminchaAteretTorah() {
1896                    return getTimeOffset(getAlos72Zmanis(),
1897                                    getShaahZmanisAteretTorah() * 10.75);
1898            }
1899    
1900            /**
1901             * Method to return <em>tzais</em> (dusk) calculated as 72 minutes
1902             * zmaniyos, or 1/10th of the day after
1903             * {@link #getSeaLevelSunset() sea level sunset}.
1904             * 
1905             * @return the <code>Date</code> representing the time.
1906             * @see #getAlos72Zmanis()
1907             */
1908            public Date getTzais72Zmanis() {
1909                    long shaahZmanis = getShaahZmanisGra();
1910                    if (shaahZmanis == Long.MIN_VALUE) {
1911                            return null;
1912                    }
1913                    return getTimeOffset(getSeaLevelSunset(), shaahZmanis * 1.2);
1914            }
1915    
1916            /**
1917             * Method to return <em>tzais</em> (dusk) calculated using 90 minutes
1918             * zmaniyos (<em>GR"A</em> and the <em>Baal Hatanya</em>) after
1919             * {@link #getSeaLevelSunset() sea level sunset}.
1920             * 
1921             * @return the <code>Date</code> representing the time.
1922             * @see #getAlos90Zmanis()
1923             */
1924            public Date getTzais90Zmanis() {
1925                    long shaahZmanis = getShaahZmanisGra();
1926                    if (shaahZmanis == Long.MIN_VALUE) {
1927                            return null;
1928                    }
1929                    return getTimeOffset(getSeaLevelSunset(), shaahZmanis * 1.5);
1930            }
1931    
1932            /**
1933             * Method to return <em>tzais</em> (dusk) calculated using 96 minutes
1934             * zmaniyos (<em>GR"A</em> and the <em>Baal Hatanya</em>) after
1935             * {@link #getSeaLevelSunset() sea level sunset}.
1936             * 
1937             * @return the <code>Date</code> representing the time.
1938             * @see #getAlos96Zmanis()
1939             */
1940            public Date getTzais96Zmanis() {
1941                    long shaahZmanis = getShaahZmanisGra();
1942                    if (shaahZmanis == Long.MIN_VALUE) {
1943                            return null;
1944                    }
1945                    return getTimeOffset(getSeaLevelSunset(), shaahZmanis * 1.6);
1946            }
1947    
1948            /**
1949             * Method to return <em>tzais</em> (dusk) calculated as 90 minutes after
1950             * sea level sunset. This method returns <em>tzais</em> (nightfall) based
1951             * on the opinion of the Magen Avraham that the time to walk the distance of
1952             * a Mil in the Ramba"m's opinion is 18 minutes for a total of 90 minutes
1953             * based on the opinion of <em>Ula</em> who calculated <em>tzais</em> as
1954             * 5 Mil after sea level shkiah (sunset). A similar calculation
1955             * {@link #getTzais19Point8Degrees()}uses solar position calculations based
1956             * on this time.
1957             * 
1958             * @return the <code>Date</code> representing the time.
1959             * @see #getTzais19Point8Degrees()
1960             * @see #getAlos90()
1961             */
1962            public Date getTzais90() {
1963                    return getTimeOffset(getSeaLevelSunset(), 90 * MINUTE_MILLIS);
1964            }
1965    
1966            /**
1967             * This method returns <em>tzais</em> (nightfall) based on the opinion of
1968             * the Magen Avraham that the time to walk the distance of a Mil in the
1969             * Ramba"ms opinion is 2/5 of an hour (24 minutes) for a total of 120
1970             * minutes based on the opinion of <em>Ula</em> who calculated
1971             * <em>tzais</em> as 5 Mil after sea level shkiah (sunset). A similar
1972             * calculation {@link #getTzais26Degrees()} uses temporal calculations based
1973             * on this time.
1974             * 
1975             * @return the <code>Date</code> representing the time.
1976             * @see #getTzais26Degrees()
1977             * @see #getAlos120()
1978             */
1979            public Date getTzais120() {
1980                    return getTimeOffset(getSeaLevelSunset(), 120 * MINUTE_MILLIS);
1981            }
1982    
1983            /**
1984             * Method to return <em>tzais</em> (dusk) calculated using 120 minutes
1985             * zmaniyos (<em>GR"A</em> and the <em>Baal Hatanya</em>) after
1986             * {@link #getSeaLevelSunset() sea level sunset}.
1987             * 
1988             * @return the <code>Date</code> representing the time.
1989             * @see #getAlos120Zmanis()
1990             */
1991            public Date getTzais120Zmanis() {
1992                    long shaahZmanis = getShaahZmanisGra();
1993                    if (shaahZmanis == Long.MIN_VALUE) {
1994                            return null;
1995                    }
1996                    return getTimeOffset(getSeaLevelSunset(), shaahZmanis * 2.0);
1997            }
1998    
1999            /**
2000             * For information on how this is calculated see the comments on
2001             * {@link #getAlos16Point1Degrees()}
2002             * 
2003             * @return the <code>Date</code> representing the time.
2004             * @see #getTzais72()
2005             * @see #getAlos16Point1Degrees() for more information on this calculation.
2006             */
2007            public Date getTzais16Point1Degrees() {
2008                    return getSunsetOffsetByDegrees(ZENITH_16_POINT_1);
2009            }
2010    
2011            /**
2012             * For information on how this is calculated see the comments on
2013             * {@link #getAlos26Degrees()}
2014             * 
2015             * @return the <code>Date</code> representing the time.
2016             * @see #getTzais120()
2017             * @see #getAlos26Degrees()
2018             */
2019            public Date getTzais26Degrees() {
2020                    return getSunsetOffsetByDegrees(ZENITH_26_DEGREES);
2021            }
2022    
2023            /**
2024             * For information on how this is calculated see the comments on
2025             * {@link #getAlos18Degrees()}
2026             * 
2027             * @return the <code>Date</code> representing the time.
2028             * @see #getAlos18Degrees()
2029             */
2030            public Date getTzais18Degrees() {
2031                    return getSunsetOffsetByDegrees(ASTRONOMICAL_ZENITH);
2032            }
2033    
2034            /**
2035             * For information on how this is calculated see the comments on
2036             * {@link #getAlos19Point8Degrees()}
2037             * 
2038             * @return the <code>Date</code> representing the time.
2039             * @see #getTzais90()
2040             * @see #getAlos19Point8Degrees()
2041             */
2042            public Date getTzais19Point8Degrees() {
2043                    return getSunsetOffsetByDegrees(ZENITH_19_POINT_8);
2044            }
2045    
2046            /**
2047             * A method to return <em>tzais</em> (dusk) calculated as 96 minutes after
2048             * sea level sunset. For information on how this is calculated see the
2049             * comments on {@link #getAlos96()}.
2050             * 
2051             * @return the <code>Date</code> representing the time.
2052             * @see #getAlos96()
2053             */
2054            public Date getTzais96() {
2055                    return getTimeOffset(getSeaLevelSunset(), 96 * MINUTE_MILLIS);
2056            }
2057    
2058            /**
2059             * A method that returns the local time for fixed <em>chatzos</em>. This
2060             * time is noon and midnight adjusted from standard time to account for the
2061             * local latitude. The 360&deg; of the globe divided by 24 calculates to
2062             * 15&deg; per hour with 4 minutes per degree, so at a longitude of 0 , 15,
2063             * 30 etc Chatzos in 12:00 noon. Lakewood, NJ whose longitude is -74.2094 is
2064             * 0.7906 away from the closest multiple of 15 at -75&deg;. This is
2065             * multiplied by 4 to yeild 3 minutes and 10 seconds for a chatzos of
2066             * 11:56:50. This method is not tied to the theoretical 15&deg; timezones,
2067             * but will adjust to the actual timezone and <a
2068             * href="http://en.wikipedia.org/wiki/Daylight_saving_time">Daylight saving
2069             * time</a>.
2070             * 
2071             * @return the Date representing the local <em>chatzos</em>
2072             * @see GeoLocation#getLocalMeanTimeOffset()
2073             */
2074            public Date getFixedLocalChatzos() {
2075                    return getTimeOffset(getDateFromTime(12.0
2076                                    - getGeoLocation().getTimeZone().getRawOffset() / HOUR_MILLIS),
2077                                    -getGeoLocation().getLocalMeanTimeOffset());
2078            }
2079    
2080            /**
2081             * A method that returns the latest <em>zman krias shema</em> (time to say
2082             * Shema in the morning) calculated as 3 hours before
2083             * {@link #getFixedLocalChatzos()}.
2084             * 
2085             * @return the <code>Date</code> of the latest zman shema.
2086             * @see #getFixedLocalChatzos()
2087             * @see #getSofZmanTfilaFixedLocal()
2088             */
2089            public Date getSofZmanShmaFixedLocal() {
2090                    return getTimeOffset(getFixedLocalChatzos(), -180 * MINUTE_MILLIS);
2091            }
2092    
2093            /**
2094             * This method returns the latest <em>zman tfila</em> (time to say the
2095             * morning prayers) calculated as 2 hours before
2096             * {@link #getFixedLocalChatzos()}.
2097             * 
2098             * @return the <code>Date</code> of the latest zman tfila.
2099             * @see #getFixedLocalChatzos()
2100             * @see #getSofZmanShmaFixedLocal()
2101             */
2102            public Date getSofZmanTfilaFixedLocal() {
2103                    return getTimeOffset(getFixedLocalChatzos(), -120 * MINUTE_MILLIS);
2104            }
2105    
2106            /**
2107             * @see java.lang.Object#equals(Object)
2108             */
2109            public boolean equals(Object object) {
2110                    if (this == object) {
2111                            return true;
2112                    }
2113                    if (!(object instanceof ComplexZmanimCalendar)) {
2114                            return false;
2115                    }
2116                    ComplexZmanimCalendar cCal = (ComplexZmanimCalendar) object;
2117                    // return getCalendar().getTime().equals(cCal.getCalendar().getTime())
2118                    return getCalendar().equals(cCal.getCalendar())
2119                                    && getGeoLocation().equals(cCal.getGeoLocation())
2120                                    && getAstronomicalCalculator().equals(
2121                                                    cCal.getAstronomicalCalculator());
2122            }
2123    
2124            /**
2125             * @see java.lang.Object#hashCode()
2126             */
2127            public int hashCode() {
2128                    int result = 17;
2129                    // needed or this and subclasses will return identical hash
2130                    result = 37 * result + getClass().hashCode();
2131                    result += 37 * result + getCalendar().hashCode();
2132                    result += 37 * result + getGeoLocation().hashCode();
2133                    result += 37 * result + getAstronomicalCalculator().hashCode();
2134                    return result;
2135            }
2136    }